Commit e531b93e authored by Andrey Filippov's avatar Andrey Filippov

skippping first trigger when changing period from non-zero

parent 7ad7815a
[*]
[*] GTKWave Analyzer v3.3.66 (w)1999-2015 BSI
[*] Sun Nov 13 06:45:09 2016
[*] Sun Nov 13 21:22:41 2016
[*]
[dumpfile] "/home/eyesis/git/x393-neon/simulation/x393_dut-20161112220344813.fst"
[dumpfile_mtime] "Sun Nov 13 06:14:56 2016"
[dumpfile_size] 452214458
[dumpfile] "/home/eyesis/git/x393-neon/simulation/x393_dut-20161113125952314.fst"
[dumpfile_mtime] "Sun Nov 13 21:20:31 2016"
[dumpfile_size] 402520126
[savefile] "/home/eyesis/git/x393-neon/cocotb/x393_cocotb_03.sav"
[timestart] 0
[timestart] 343131100
[size] 1814 1171
[pos] 0 0
*-26.654955 551210000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
*-15.683622 343290000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] x393_dut.
[treeopen] x393_dut.simul_sensor12bits_2_i.
[treeopen] x393_dut.simul_sensor12bits_3_i.
......@@ -56,8 +56,8 @@
[treeopen] x393_dut.x393_i.timing393_i.
[treeopen] x393_dut.x393_i.timing393_i.camsync393_i.
[treeopen] x393_dut.x393_i.timing393_i.camsync393_i.i_frsync_pclk0.
[sst_width] 383
[signals_width] 329
[sst_width] 281
[signals_width] 276
[sst_expanded] 1
[sst_vpaned_height] 486
@820
......@@ -270,14 +270,37 @@ x393_dut.x393_i.timing393_i.rtc393_i.refclk2x_mclk
-clocks
@800200
-synchronization
@c00200
-sens_sync
@28
x393_dut.x393_i.sensors393_i.sensor_channel_block[0].sensor_channel_i.sens_sync_i.trig
x393_dut.x393_i.sensors393_i.sensor_channel_block[1].sensor_channel_i.sens_sync_i.trig
x393_dut.x393_i.sensors393_i.sensor_channel_block[2].sensor_channel_i.sens_sync_i.trig
x393_dut.x393_i.sensors393_i.sensor_channel_block[3].sensor_channel_i.sens_sync_i.trig
@1000200
@1401200
-sens_sync
@28
x393_dut.x393_i.timing393_i.camsync393_i.suppress_immediate_set_mclk
x393_dut.x393_i.timing393_i.camsync393_i.suppress_immediate_set_pclk
x393_dut.x393_i.timing393_i.camsync393_i.suppress_immediate
@c00028
x393_dut.x393_i.timing393_i.camsync393_i.start_pclk[2:0]
@28
(0)x393_dut.x393_i.timing393_i.camsync393_i.start_pclk[2:0]
(1)x393_dut.x393_i.timing393_i.camsync393_i.start_pclk[2:0]
(2)x393_dut.x393_i.timing393_i.camsync393_i.start_pclk[2:0]
@1401200
-group_end
@28
x393_dut.x393_i.timing393_i.camsync393_i.start_pclk2_masked
x393_dut.x393_i.timing393_i.camsync393_i.set_period
x393_dut.x393_i.timing393_i.camsync393_i.pre_start0
x393_dut.x393_i.timing393_i.camsync393_i.start0
x393_dut.x393_i.timing393_i.camsync393_i.start
x393_dut.x393_i.timing393_i.camsync393_i.start_d
x393_dut.x393_i.timing393_i.camsync393_i.start_en
x393_dut.x393_i.timing393_i.camsync393_i.rep_en
x393_dut.x393_i.timing393_i.camsync393_i.set_period
@c00028
x393_dut.x393_i.timing393_i.camsync393_i.ext_int_arm[1:0]
@28
......@@ -325,8 +348,16 @@ x393_dut.x393_i.timing393_i.camsync393_i.start_late_first
x393_dut.x393_i.timing393_i.camsync393_i.start_late
x393_dut.x393_i.timing393_i.camsync393_i.armed_internal_trigger
x393_dut.x393_i.timing393_i.camsync393_i.start_dly
[color] 2
x393_dut.x393_i.timing393_i.camsync393_i.start_to_pclk
@22
x393_dut.x393_i.timing393_i.camsync393_i.restart_cntr[31:0]
@28
x393_dut.x393_i.timing393_i.camsync393_i.restart_cntr_run[1:0]
[color] 2
x393_dut.x393_i.timing393_i.camsync393_i.restart
@800022
[color] 3
x393_dut.x393_i.timing393_i.camsync393_i.start_pclk[2:0]
@28
(0)x393_dut.x393_i.timing393_i.camsync393_i.start_pclk[2:0]
......@@ -2347,7 +2378,6 @@ x393_dut.x393_i.event_logger_i.data_out_stb
x393_dut.x393_i.event_logger_i.sample_counter[23:0]
@28
x393_dut.GPS1SEC
@29
x393_dut.ODOMETER_PULSE
@c00200
-x393
......@@ -2361,8 +2391,9 @@ x393_dut.x393_i.logger_stb
-buf_xclk_mclk
@1000200
-buf_xclk_mclk
@28
@29
x393_dut.x393_i.event_logger_i.mux_data_valid
@28
x393_dut.x393_i.event_logger_i.ts_en
@22
x393_dut.x393_i.event_logger_i.timestamps_rdata[15:0]
......
......@@ -35,7 +35,8 @@
* contains all the components and scripts required to completely simulate it
* with at least one of the Free Software programs.
*/
parameter FPGA_VERSION = 32'h039300ca; //parallel - and more ... -0.267/46, 80.42%
parameter FPGA_VERSION = 32'h039300cb; //parallel - modifying trigger/timestamps -0.050/13 80.38%
// parameter FPGA_VERSION = 32'h039300ca; //parallel - and more ... fixed -0.267/46, 80.42%
// parameter FPGA_VERSION = 32'h039300c9; //parallel - trying more ...-0.123/32 79.82%
// parameter FPGA_VERSION = 32'h039300c8; //parallel - trying to fix "premature..." -0.121/21, 80.2%
// parameter FPGA_VERSION = 32'h039300c7; //parallel - disable SoF when channel disabled: met, 80.32%
......
......@@ -2650,6 +2650,212 @@ jpeg_sim_multi 4
jpeg_sim_multi 4
################## Simulate Parallel 15 - internal trigger ####################
./py393/test_mcntrl.py @py393/cocoargs --simulated=localhost:7777
measure_all "*DI"
setup_all_sensors True None 0xf
#set_sensor_io_ctl all None None 1 # Set ARO low - check if it is still needed?
#use EOF instead of SOF for i2c sequencer advance
set_sensor_i2c_command all False None None None None None None True
#just testing
set_gpio_ports 1 1 # enable software gpio pins and porta (camsync)
set_gpio_pins 0 1 # pin 0 low, pin 1 - high
set_logger_params_file "/home/eyesis/git/x393-neon/attic/imu_config.bin"
##### write_control_register 0x480 0x400 # disable sensor chn 2
reset_camsync_inout 1 # reset all outputs
set_camsync_period 31 # set bit duration
set_camsync_period 0 # disable
set_camsync_delay 0 400
set_camsync_delay 1 100
set_camsync_delay 2 200
set_camsync_delay 3 300
#set_camsync_inout <is_out> <bit_number> <active_positive>
###set_camsync_inout 1 8 0
###set_camsync_inout 0 7 0
reset_camsync_inout 0 # start with internal trigger
#set_camsync_mode <en=None> <en_snd=None> <en_ts_external=None> <triggered_mode=None> <master_chn=None> <chn_en=None>
set_camsync_mode 1 1 1 1 0 0xf
set_camsync_period 0 # so next setting period will immadiately trigger
set_camsync_period 8000 # 80 usec #and issue first trigger
set_sensor_histogram_window 0 0 4 4 25 21
set_sensor_histogram_window 1 0 4 4 41 21
set_sensor_histogram_window 2 0 4 4 25 41
set_sensor_histogram_window 3 0 4 4 41 41
r
read_control_register 0x430
read_control_register 0x431
write_cmd_frame_sequencer 0 1 2 0x600 0x48 # compressor q page = 1 // too late for frame 2
set_qtables 0 0 80
set_qtables 0 1 70
#irq coming, image not changing - yes
write_cmd_frame_sequencer 0 1 1 0x686 0x280005 #save 4 more lines than sensor has
write_cmd_frame_sequencer 0 1 1 0x680 0x5507 #enable abort
#write_cmd_frame_sequencer 0 1 1 0x6c6 0x300006 #save 4 more lines that compressor has
write_cmd_frame_sequencer 0 1 2 0x600 0x5 #stop compressor `
write_cmd_frame_sequencer 0 1 2 0x680 0x5405 # stop sensor memory (+0) // sensor memory should be controlled first, (9 commands
write_cmd_frame_sequencer 0 1 2 0x6c0 0x5c49 # stop compressor memory (+0)
write_cmd_frame_sequencer 0 1 3 0x686 0x240005 # correct lines
write_cmd_frame_sequencer 0 1 3 0x680 0x5507 # run sensor memory (+1) Can not be 0
write_cmd_frame_sequencer 0 1 4 0x686 0x280005 #save 4 more lines than sensor has
write_cmd_frame_sequencer 0 1 4 0x6c6 0x300006 #save more lines than compressor needs (sensor provides)
write_cmd_frame_sequencer 0 1 4 0x6c0 0x7d4b # run compressor memory (+2)
write_cmd_frame_sequencer 0 1 4 0x600 0x7 # run compressor (+0)
write_cmd_frame_sequencer 0 1 1 0x600 0x48 # compressor q page = 1
write_cmd_frame_sequencer 0 1 4 0x600 0x40 # compressor q page = 0
read_control_register 0x431
read_control_register 0x430
#testing histograms
write_control_register 0x409 0xc0
#set_sensor_io_dly_hispi all 0x48 0x68 0x68 0x68 0x68
#set_sensor_io_ctl all None None None None None 1 None # load all delays?
compressor_control all None None None None None 2
compressor_interrupt_control all clr
compressor_interrupt_control all en
compressor_control all 3
r
read_status 0x21
r
jpeg_sim_multi 4
set_camsync_period 9000 # 90 usec # change period, skip first trigger
r
read_status 0x21
r
jpeg_sim_multi 3
r
read_status 0x21
r
write_cmd_frame_sequencer 0 1 1 0x686 0x240005 # correct lines
write_cmd_frame_sequencer 0 1 1 0x6c6 0x200006 # correct lines
write_cmd_frame_sequencer 0 1 1 0x680 0x5507 # run sensor memory, update frame#, reset buffers
write_cmd_frame_sequencer 0 1 1 0x6c0 0x7d4b # run compressor memory
write_cmd_frame_sequencer 0 1 1 0x600 0x7 # run compressor
#switch to external (wired) trigger
jpeg_sim_multi 4
### set_camsync_inout 0 9 0 # external/internal trigger mode
###switch to external (wired) trigger
##set_camsync_inout 0 7 0
jpeg_sim_multi 4
#set_camsync_mode <en=None> <en_snd=None> <en_ts_external=None> <triggered_mode=None> <master_chn=None> <chn_en=None>
jpeg_sim_multi 8
###set_camsync_period 8000 # 80 usec - restart while waiting for external trigger
jpeg_sim_multi 4
jpeg_sim_multi 4
################## Simulate Parallel 16 - free running (all the same, but keep free running mode) ####################
./py393/test_mcntrl.py @py393/cocoargs --simulated=localhost:7777
measure_all "*DI"
setup_all_sensors True None 0xf
#Setting ARO for free run mode?
set_sensor_io_ctl all None None 1 # Set ARO low - check if it is still needed?
#use EOF instead of SOF for i2c sequencer advance
set_sensor_i2c_command all False None None None None None None True
#just testing
set_gpio_ports 1 1 # enable software gpio pins and porta (camsync)
set_gpio_pins 0 1 # pin 0 low, pin 1 - high
set_logger_params_file "/home/eyesis/git/x393-neon/attic/imu_config.bin"
##### write_control_register 0x480 0x400 # disable sensor chn 2
reset_camsync_inout 1 # reset all outputs
set_camsync_period 31 # set bit duration
set_camsync_period 0 # disable
set_camsync_delay 0 400
set_camsync_delay 1 100
set_camsync_delay 2 200
set_camsync_delay 3 300
#set_camsync_inout <is_out> <bit_number> <active_positive>
###set_camsync_inout 1 8 0
###set_camsync_inout 0 7 0
reset_camsync_inout 0 # start with internal trigger
#set_camsync_mode <en=None> <en_snd=None> <en_ts_external=None> <triggered_mode=None> <master_chn=None> <chn_en=None>
#### set_camsync_mode 1 1 1 1 0 0xf # keep
set_camsync_mode 1 1 1 0 0 0xf # keep free running mode, do not switch to triggered
set_camsync_period 0 # so next setting period will immadiately trigger
set_camsync_period 8000 # 80 usec #and issue first trigger
set_sensor_histogram_window 0 0 4 4 25 21
set_sensor_histogram_window 1 0 4 4 41 21
set_sensor_histogram_window 2 0 4 4 25 41
set_sensor_histogram_window 3 0 4 4 41 41
r
read_control_register 0x430
read_control_register 0x431
write_cmd_frame_sequencer 0 1 2 0x600 0x48 # compressor q page = 1 // too late for frame 2
set_qtables 0 0 80
set_qtables 0 1 70
#irq coming, image not changing - yes
write_cmd_frame_sequencer 0 1 1 0x686 0x280005 #save 4 more lines than sensor has
write_cmd_frame_sequencer 0 1 1 0x680 0x5507 #enable abort
#write_cmd_frame_sequencer 0 1 1 0x6c6 0x300006 #save 4 more lines that compressor has
write_cmd_frame_sequencer 0 1 2 0x600 0x5 #stop compressor `
write_cmd_frame_sequencer 0 1 2 0x680 0x5405 # stop sensor memory (+0) // sensor memory should be controlled first, (9 commands
write_cmd_frame_sequencer 0 1 2 0x6c0 0x5c49 # stop compressor memory (+0)
write_cmd_frame_sequencer 0 1 3 0x686 0x240005 # correct lines
write_cmd_frame_sequencer 0 1 3 0x680 0x5507 # run sensor memory (+1) Can not be 0
write_cmd_frame_sequencer 0 1 4 0x686 0x280005 #save 4 more lines than sensor has
write_cmd_frame_sequencer 0 1 4 0x6c6 0x300006 #save more lines than compressor needs (sensor provides)
write_cmd_frame_sequencer 0 1 4 0x6c0 0x7d4b # run compressor memory (+2)
write_cmd_frame_sequencer 0 1 4 0x600 0x7 # run compressor (+0)
write_cmd_frame_sequencer 0 1 1 0x600 0x48 # compressor q page = 1
write_cmd_frame_sequencer 0 1 4 0x600 0x40 # compressor q page = 0
read_control_register 0x431
read_control_register 0x430
#testing histograms
write_control_register 0x409 0xc0
#set_sensor_io_dly_hispi all 0x48 0x68 0x68 0x68 0x68
#set_sensor_io_ctl all None None None None None 1 None # load all delays?
compressor_control all None None None None None 2
compressor_interrupt_control all clr
compressor_interrupt_control all en
compressor_control all 3
r
read_status 0x21
r
jpeg_sim_multi 4
jpeg_sim_multi 4
jpeg_sim_multi 12
################## Serial ####################
cd /usr/local/verilog/; test_mcntrl.py @hargs
......
......@@ -256,6 +256,7 @@ module camsync393 #(
reg [31:0] repeat_period; // restart period in repetitive mode
reg start,start_d; // start single/repetitive output pulse(s)
reg rep_en; // enable repetitive mode
reg rep_en_pclk;
reg start_en;
wire start_to_pclk;
reg [2:0] start_pclk; // start and restart
......@@ -324,8 +325,10 @@ module camsync393 #(
reg ts_external_pclk; // 1 - use external timestamp (combines ts_external and input_use_intern)
reg triggered_mode_pclk;
reg armed_internal_trigger; // to prevent re-start as in internal trigger mode timestamp over for master channel trigger s the sequence
// and that timestmp is acquired fro each delayed channel (includin master) again
reg armed_internal_trigger; // to prevent re-start as in internal trigger mode timestamp
// over for master channel triggers the sequence
// and that timestmp is acquired for each delayed channel (including master) again
// Is it still needed after mods or should be removed (likely)
wire [3:0] local_got; // received local timestamp (@ posedge mclk)
wire [3:0] local_got_pclk; // local_got reclocked @pclk
......@@ -361,7 +364,14 @@ module camsync393 #(
wire [3:0] pending_latest = frsync_pend | {4{received_or_master_pending}};
reg [3:0] pending_latest_d;
reg [3:0] ts_stb_pclk_r;
reg start_early;
reg start_early;
reg suppress_immediate_set_mclk; // even single after repetitive will be suppressed (0 should be written first)
wire suppress_immediate_set_pclk;
reg suppress_immediate; // suppress first trigger if period was not 0 (to avoid re-started frames)
wire start_pclk2_masked= start_pclk[2] && !suppress_immediate;
// reg
......@@ -395,8 +405,8 @@ module camsync393 #(
assign restart= restart_cntr_run[1] && !restart_cntr_run[0];
assign pre_set_bit= (|cmd_data[31:8]==0) && |cmd_data[7:1]; // 2..255
assign pre_start0= |cmd_data[31:0] && !pre_set_bit;
assign pre_set_period = !pre_set_bit;
assign pre_start0= |cmd_data[31:0] && !pre_set_bit; // 1, 256...
assign pre_set_period = !pre_set_bit;
assign {trig_chn3, trig_chn2, trig_chn1, trig_chn0} = trig_r_mclk;
......@@ -509,81 +519,44 @@ module camsync393 #(
start_en <= en && (repeat_period[31:0]!=0);
if (!en) rep_en <= 0;
// if (!en) rep_en <= 0;
if (mrst) rep_en <= 0;
else if (set_period) rep_en <= !high_zero;
suppress_immediate_set_mclk <= set_period && rep_en && en; // even single will be suppressed if not after stopped/single
ext_int_mode_mclk <= input_use[CAMSYNC_GPIO_EXT_IN] && !gpio_out_en_r[CAMSYNC_GPIO_EXT_OUT] &&
input_use[CAMSYNC_GPIO_INT_IN] && gpio_out_en_r[CAMSYNC_GPIO_INT_OUT];
end
/*
always @ (posedge pclk) begin
ts_to_send <= chn_en & (ts_snap_triggered | (ts_to_send & ~local_got_pclk));
end
always @ (posedge pclk) begin
case (master_chn)
2'h0: if (local_got_pclk[0] & ts_to_send[0]) begin
ts_snd_sec <= ts_snd_sec_chn0;
ts_snd_usec <= ts_snd_usec_chn0;
end
2'h1: if (local_got_pclk[1] & ts_to_send[1])begin
ts_snd_sec <= ts_snd_sec_chn1;
ts_snd_usec <= ts_snd_usec_chn1;
end
2'h2: if (local_got_pclk[2] & ts_to_send[2])begin
ts_snd_sec <= ts_snd_sec_chn2;
ts_snd_usec <= ts_snd_usec_chn2;
end
2'h3: if (local_got_pclk[3] & ts_to_send[3])begin
ts_snd_sec <= ts_snd_sec_chn3;
ts_snd_usec <= ts_snd_usec_chn3;
end
endcase
end
*/
always @ (posedge pclk) begin
chn_en_pclk <= chn_en;
rep_en_pclk <= rep_en && en;
if (!en_pclk || start_pclk[2]) suppress_immediate <= 0;
else if (suppress_immediate_set_pclk) suppress_immediate <= 1;
if (!input_use_intern || start_late) armed_internal_trigger <= 0;
else if (start_pclk[2]) armed_internal_trigger <= 1;
/*
ts_snap_triggered <= chn_en & ({4{(start_pclk[2] & ts_snd_en_pclk)}} | //strobe by internal generator if output timestamp is enabled
(trig_r & ~{4{ts_external_pclk}})); // get local timestamp of the trigger (ext/int)
*/
// now only at frame sync, others are handled by master timestamp
ts_snap_triggered <= chn_en_pclk & trig_r; // get local timestamp of the trigger (ext/int). Non-trigger-mode will use frame sync instead
// request master timestamp at start if it is sent out or at receive (if it is not). ts_snd_en_pclk should be 0 if incoming sync does not have timestamps
ts_master_snap_pclk <= ts_snd_en_pclk? start_pclk[2]: rcv_done;
/// ts_master_snap_pclk <= ts_snd_en_pclk? start_pclk[2]: rcv_done;
ts_master_snap_pclk <= ts_snd_en_pclk? start_pclk2_masked: rcv_done;
/*
if (ts_external_pclk) begin
if (ts_snd_en_pclk ||input_use_intern ) ts_snap_triggered <= chn_en_pclk & {4{start_pclk[2]}}; // when the trigger pulse is generated
else ts_snap_triggered <= chn_en_pclk & {4{rcv_done}}; // when the external trigger pulse is received (TODO: Eyesis ext. mode?)
end else begin // use local timestamps (per-channel individual)
ts_snap_triggered <= trig_r;
end
*/
ts_snd_en_pclk<=ts_snd_en;
input_use_intern <= pre_input_use_intern;
ts_external_pclk<= ts_external; // && !input_use_intern;
start_pclk[2:0] <= {(restart && rep_en) ||
// (start_pclk[1] && !restart_cntr_run[1] && !restart_cntr_run[0] && !start_pclk[2]), // does not allow to restart
start_pclk[2:0] <= {(restart && rep_en_pclk) ||
(start_pclk[1] && !start_pclk[2]), // allows to restart running or armed counter
start_pclk[0],
start_to_pclk && !start_pclk[0]};
// restart_cntr_run[1:0] <= {restart_cntr_run[0],start_en && (start_pclk[2] || (restart_cntr_run[0] && (restart_cntr[31:2] !=0)))};
//
// if (restart_cntr_run[0]) restart_cntr[31:0] <= restart_cntr[31:0] - 1;
// else restart_cntr[31:0] <= repeat_period[31:0];
restart_cntr_run[1:0] <= {restart_cntr_run[0],start_en && (start_pclk[2] || (restart_cntr_run[0] && !ext_int_arm[1] && !start_pclk[0]))};
if (restart_cntr_run[0]) begin
......@@ -700,11 +673,14 @@ module camsync393 #(
(rcv_run && !rcv_run_d); // all start at the same time - master/others
/// start_early <=input_use_intern ?
/// (start_pclk[2] && start_en) :
/// (rcv_run && !rcv_run_d); // all start at the same time - master/others
start_early <=input_use_intern ?
(start_pclk[2] && start_en) :
(start_pclk2_masked && start_en) :
(rcv_run && !rcv_run_d); // all start at the same time - master/others
//
// simulation problems w/o "start_en &&" ?
dly_cntr_run_d <= dly_cntr_run;
......@@ -847,8 +823,8 @@ module camsync393 #(
// rcv_done_mclk - make it either really received or from FPGA if internal?
// Making delayed start that waits for timestamp use timestamp_got, otherwise - nothing to wait
/// assign start_late = ts_snd_en_pclk?local_got_pclk[master_chn] : start_pclk[2];
assign start_late = ts_snd_en_pclk?master_got_pclk : start_pclk[2];
/// assign start_late = ts_snd_en_pclk?master_got_pclk : start_pclk[2];
assign start_late = ts_snd_en_pclk?master_got_pclk : start_pclk2_masked;
assign start_late_first = start_late && (armed_internal_trigger|| !ts_snd_en_pclk);
cmd_deser #(
......@@ -993,6 +969,7 @@ module camsync393 #(
pulse_cross_clock i_ts_stb_mclk2 (.rst(eprst), .src_clk(pclk), .dst_clk(mclk), .in_pulse(ts_stb_pclk_r[2]), .out_pulse(ts_stb[2]),.busy());
pulse_cross_clock i_ts_stb_mclk3 (.rst(eprst), .src_clk(pclk), .dst_clk(mclk), .in_pulse(ts_stb_pclk_r[3]), .out_pulse(ts_stb[3]),.busy());
pulse_cross_clock i_suppress_immediate_set_pclk(.rst(!en), .src_clk(mclk), .dst_clk(pclk), .in_pulse(suppress_immediate_set_mclk), .out_pulse(suppress_immediate_set_pclk),.busy());
endmodule
......
No preview for this file type
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