Commit 0fd824fb authored by CLAUDEPIERRE Ludovic's avatar CLAUDEPIERRE Ludovic
Browse files

Clean Code, version fonctionnelle, entrée UART byte par byte, max burst = 32

parent 94b2d16a
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 25.03.2020 10:08:11
-- Design Name:
-- Module Name: traitor_tb - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
use work.triggy_common.all;
use work.common.all;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
library UNISIM;
use UNISIM.VComponents.all;
entity config_manager_tb is
end config_manager_tb;
architecture Behavioral of config_manager_tb is
procedure wait_clocks(signal clk : in std_logic; n : in integer) is
begin
for i in 1 to n loop
wait until falling_edge(clk);
end loop;
end procedure;
constant T : time := 20 ns;
signal clk: std_logic := '0';
signal reset: std_logic;
component configuration_manager is
port(clk: in std_logic;
reset: in std_logic;
--fifo from Uart PC rx (cross clock domains)
din: in byte;
din_rdy: in std_logic;
din_read: out std_logic;-- send read order
--fifo to Uart PC tx (cross clock domains)
dout: out byte;
dout_write: out std_logic;-- send write order
-- triggers
trig_amplitude : out std_logic_vector(7 downto 0);
trig_confs: out TrigConfs
);
end component;
component fifo IS
PORT (
clk : IN STD_LOGIC;
rst : IN STD_LOGIC;
din : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
wr_en : IN STD_LOGIC;
wr_rst_busy : OUT STD_LOGIC;
rd_en : IN STD_LOGIC;
rd_rst_busy : OUT STD_LOGIC;
dout : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
full : OUT STD_LOGIC;
empty : OUT STD_LOGIC
);
end component;
-- fifo rx
signal fifo_rx_dout: std_logic_vector(7 downto 0);
signal fifo_rx_available, fifo_rx_empty, fifo_rx_read_order: std_logic;
-- fifo tx
signal fifo_tx_dout, fifo_tx_din: std_logic_vector(7 downto 0);
signal fifo_tx_empty, fifo_tx_write_order, fifo_tx_read: std_logic;
signal trig_confs: TrigConfs;
signal pc_rx_data: std_logic_vector(7 downto 0);
signal pc_rx_write : std_logic;
begin
clk <= not clk after T/2;
-- reset = 1 for first clock cycle and then 0
reset <= '1', '0' after T/2;
pc_uart_rx_fifo: fifo
port map(
rst => reset,
clk => clk,
din => pc_rx_data,
wr_en => pc_rx_write,
rd_en => fifo_rx_read_order,
dout => fifo_rx_dout,
rd_rst_busy => open,
wr_rst_busy => open,
full => open,
empty => fifo_rx_empty
);
fifo_rx_available <= not(fifo_rx_empty);
pc_uart_tx_fifo: fifo
port map(
rst => reset,
clk => clk,
din => fifo_tx_din,
wr_en => fifo_tx_write_order,
rd_en => fifo_tx_read,
dout => fifo_tx_dout,
rd_rst_busy => open,
wr_rst_busy => open,
full => open,
empty => fifo_tx_empty
);
dut: configuration_manager
port map (
clk => clk,
reset => reset,
din => fifo_rx_dout,
din_rdy => fifo_rx_available,
din_read => fifo_rx_read_order,
dout => fifo_tx_din,
dout_write => fifo_tx_write_order,
trig_amplitude => open,
trig_confs => trig_confs
);
fifo_tx_read <= '0';
-- now we send data to fifo_rx: 00 00 07 (read at address 00 07)
test: process
begin
pc_rx_data <= x"00";
pc_rx_write <= '0';
wait_clocks(clk, 5);
-- push 00 to fifo rx
pc_rx_data <= x"00";
pc_rx_write <= '1';
wait_clocks(clk, 1);
--push 00 again
-- we repeat so we do not change the signals
wait_clocks(clk, 1);
-- push 07
pc_rx_data <= x"07";
wait_clocks(clk, 1);
-- stop pushing
pc_rx_write <= '0';
-- wait end of simu
wait_clocks(clk, 10);
end process;
end Behavioral;
......@@ -2,12 +2,12 @@
-- Company: INRIA
-- Engineer: Ludovic Claudepierre
--
-- Create Date: 31.10.2018 16:33:09
-- Create Date: 19.11.2018 16:33:09
-- Design Name:
-- Module Name: PLL_clk - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Project Name: TRAITOR
-- Target Devices: ArtiX7
-- Tool Versions: v1
-- Description:
--
-- Dependencies:
......@@ -55,11 +55,6 @@ end mmcm_reset;
architecture Behavioral of mmcm_reset is
-- signal btn_meta : std_logic := '0';
-- signal btn : std_logic := '0';
-- signal speed_select : std_logic := '0';
-- signal counter : std_logic_vector(26 downto 0) := (others => '0');
-- signal debounce : std_logic_vector(15 downto 0) := (others => '0');
signal clk_0 : std_logic := '0';
signal clk_1 : std_logic := '0';
signal clk_0nb : std_logic := '0';
......@@ -68,9 +63,6 @@ architecture Behavioral of mmcm_reset is
type t_state is (state_wait, state_enable, state_plus, state_moins, state_end);
signal state : t_state := state_wait;
-----------------------------------------------------------------------------
--- This is the CLKOUT0 ClkReg1 address - the only register to be played with
-----------------------------------------------------------------------------
......@@ -114,16 +106,7 @@ architecture Behavioral of mmcm_reset is
signal btn_Dplus_b2 : std_logic := '0';
signal btn_Dmoins_b2 : std_logic := '0';
-- signal Delay1 : std_logic_vector(31 downto 0) ; --"0000000000100000";--
-- signal Delay2 : std_logic_vector(31 downto 0); --"0000000001101100";--
-- signal Delay3 : std_logic_vector(31 downto 0) ;
-- signal Delay4 : std_logic_vector(31 downto 0) ;
signal Dcount_led : std_logic_vector(15 downto 0) := "0000000000000000";
-- signal Delay12 : std_logic_vector(15 downto 0);
-- signal Delay123 : std_logic_vector(15 downto 0);
-- signal Dcount : std_logic_vector(15 downto 0) := "0000000000000000";
-- signal Nfault : std_logic_vector(1 downto 0);
-- signal kfault : std_logic_vector(1 downto 0):="00";
constant Nfault: Integer := NB_TRIGGERS;
shared variable Dcount : integer :=0;
shared variable kfault: Integer := 0;
......@@ -255,14 +238,6 @@ stm_evt<=(stm_trig_b xor stm_trig_b2) and stm_trig_b ;
CLKFBIN => clk_fb
);
--triggers confs
--gen_delay: for i in 0 to NB_TRIGGERS-1 generate
-- v_delay(i) <= unsigned(mem_glitch((TRIGGERS_ADD+i*TRIGGER_CONF_SIZE)*8 + 31 downto (TRIGGERS_ADD+i*TRIGGER_CONF_SIZE)*8));
-- v__width(i) <=unsigned(mem_glitch((TRIGGERS_ADD+i*TRIGGER_CONF_SIZE)*8 + 63 downto (TRIGGERS_ADD+i*TRIGGER_CONF_SIZE)*8 + 32));
--end generate;
phase_change_fsm: process(s_PSCLK)
begin
if rising_edge(s_PSCLK) then
......
......@@ -25,19 +25,6 @@ end configuration_manager;
architecture behavior of configuration_manager is
component ila_0 IS
PORT(
clk : in STD_LOGIC; -- clk
probe0 : in STD_LOGIC_VECTOR (2 downto 0); -- state
probe1 : in STD_LOGIC_VECTOR (0 downto 0); -- read_en
probe2 : in STD_LOGIC_VECTOR (15 downto 0); -- v_address
probe3 : in STD_LOGIC_VECTOR (7 downto 0); -- databyte
probe4 : in STD_LOGIC_VECTOR (3 downto 0); --countadd
probe5 : in STD_LOGIC_VECTOR (0 downto 0) --crw
);
end component;
component fifo_autoreader is
port(clk: in std_logic;
reset: in std_logic;
......@@ -52,7 +39,7 @@ end component;
end component;
-- protocel is [address(15 downto 0), payload_len(7 downto 0), data(8*payload_len-1 downto 0)]
type COMMAND_FSM_STATE is (FUN, ADD, WRITE_DATA, READ_DATA, WAIT1, TRIG_IMM, SEND_CHECKSUM); -- FUN is skipped
type COMMAND_FSM_STATE is (FUN, ADD, WRITE_DATA, READ_DATA, WAIT1, SEND_CHECKSUM); -- FUN is skipped
signal data_byte: byte;
signal data_en: std_logic;
......@@ -70,17 +57,11 @@ end component;
signal address: integer range 0 to 255;
signal count_add: integer range 0 to 255;
signal crw: std_logic; -- 0 read 1 write
signal v_count_add: std_logic_vector(3 downto 0); -- 0 read 1 write
signal v_crw: std_logic_vector(0 downto 0); -- 0 read 1 write
signal v_data_en: std_logic_vector(0 downto 0); -- 0 read 1 write
signal autoread_enable: std_logic;
signal action_reg, dout_buf, checksum: byte;
signal action: std_logic;
signal dout_buf, checksum: byte;
-- signal uart_trig_conf_seq : UartSequence;
-- signal apdu_header: APDUHeader;
begin
......@@ -88,8 +69,8 @@ end component;
dout <= dout_buf;
dout_write <= dout_write_order;
autoread_enable <= '1';
v_data_en(0)<=data_en;
v_crw(0)<=crw;
-- v_data_en(0)<=data_en;
-- v_crw(0)<=crw;
-- Memory mapping
--triggers confs
......@@ -99,12 +80,11 @@ begin
for i in 0 to NB_TRIGGERS-1 loop
trig_confs(i).trig_delay <= unsigned(mem((i*LENGTH_TRIG_CONFS + LENGTH_DELAY+LENGTH_AMPLITUDE)*8-1 downto (i*LENGTH_TRIG_CONFS+LENGTH_AMPLITUDE)*8));
trig_confs(i).trig_width <= unsigned(mem((i*LENGTH_TRIG_CONFS + LENGTH_DELAY+LENGTH_WIDTH+LENGTH_AMPLITUDE)*8-1 downto (i*LENGTH_TRIG_CONFS + LENGTH_DELAY+LENGTH_AMPLITUDE)*8));
-- mem((i*LENGTH_PACKET_CONFS + LENGTH_MEM+LENGTH_WIDTH+LENGTH_DIRECTION)*8-1 downto (i*LENGTH_PACKET_CONFS + LENGTH_MEM+LENGTH_WIDTH)*8) <= std_logic_vector(packet_confs(i).packet_direction);
end loop;
end process;
v_count_add <= std_logic_vector(to_unsigned(count_add,4));
--v_count_add <= std_logic_vector(to_unsigned(count_add,4));
address <= to_integer(unsigned(v_address));
-- mem operations
......@@ -121,18 +101,6 @@ address <= to_integer(unsigned(v_address));
data_en => data_en
);
ila : ila_0
port map(
clk => clk,
probe0 => v_state,
probe1 => v_data_en,
probe2 => v_address,--packet2send,
probe3 => data_byte,
probe4 => v_count_add,
probe5 => v_crw
);
update_mem: process(clk, reset)
begin
if reset = '1' then
......@@ -141,9 +109,6 @@ ila : ila_0
if command_state = READ_DATA and data_en = '1' then
mem(address*8+7 downto address*8) <= data_byte;
end if;
-- if counter_updated = '1' then
-- mem((COUNTER_ADD+COUNTER_SIZE)*8-1 downto COUNTER_ADD*8) <= std_logic_vector(counter_value);
-- end if;
end if;
end process;
......@@ -152,9 +117,9 @@ ila : ila_0
if reset = '1' then
checksum <= X"00";
elsif rising_edge(clk) then
if command_state = SEND_CHECKSUM then
if command_state = FUN then
checksum <= X"00";
elsif data_en = '1' then
elsif command_state = WRITE_DATA or command_state = READ_DATA then
checksum <= v_address(7 downto 0);-- checksum xor data_byte;
end if;
end if;
......@@ -211,9 +176,6 @@ ila : ila_0
elsif data_byte = X"01" then
crw <= '1';
command_state <= ADD;
elsif data_byte = X"02" then
crw <= '1';
command_state <= TRIG_IMM;
else -- test
crw <= '0';
command_state <= SEND_CHECKSUM;
......@@ -222,17 +184,10 @@ ila : ila_0
command_state <= FUN;
end if;
when TRIG_IMM =>
v_state<="111";
if data_en = '1' then
command_state <= SEND_CHECKSUM;
else
command_state <= TRIG_IMM;
end if;
when ADD =>
v_state<="001";
if data_en = '1' and count_add>1 then
if data_en = '1' then --and count_add>=1 then
if crw = '1' then --write mode expect data value
command_state <= READ_DATA;
else
......
......@@ -15,61 +15,22 @@ package triggy_common is
constant TRIGGER_CONF_SIZE: Integer := 9;-- 17;
constant NB_TRIGGERS: Integer := 64;
-- constant APDU_FOLLOWER_CONFIG_ADD: Integer := TRIGGERS_ADD+TRIGGER_CONF_SIZE*NB_TRIGGERS;-- 1+9*4 //--1+17*4=69
-- constant APDU_FOLLOWER_CONFIG_SIZE: Integer := 1;
-- constant APDU_FOLLOWER_WAIT_COUNTER_ADD: Integer := APDU_FOLLOWER_CONFIG_ADD+APDU_FOLLOWER_CONFIG_SIZE;--38 //--70
-- constant APDU_FOLLOWER_WAIT_COUNTER_SIZE: Integer := 4;
-- constant APDU_FOLLOWER_HEADER_SELECT_ADD: Integer := APDU_FOLLOWER_WAIT_COUNTER_ADD+APDU_FOLLOWER_WAIT_COUNTER_SIZE;--42 //--74
-- constant APDU_FOLLOWER_HEADER_SELECT_SIZE: Integer := 4;
-- constant COUNTER_ADD: Integer := APDU_FOLLOWER_HEADER_SELECT_ADD+APDU_FOLLOWER_HEADER_SELECT_SIZE;--46 //--78
-- constant COUNTER_SIZE: Integer := 4;
-- constant SEQUENCE_SIZE: Integer := 8;
-- constant UART_INTERCEPT_STEP_ADD: Integer := COUNTER_ADD+COUNTER_SIZE;--50 //--82
-- constant UART_INTERCEPT_STEP_SIZE: Integer := 4;
-- constant UART_INTERCEPT_CONFIG_ADD: Integer := UART_INTERCEPT_STEP_ADD+UART_INTERCEPT_STEP_SIZE;-- 54 //--86
-- constant UART_INTERCEPT_CONFIG_SIZE: Integer := 1;
-- constant UART_INTERCEPT_SEQ_SIZE_ADD: Integer := UART_INTERCEPT_CONFIG_ADD+UART_INTERCEPT_CONFIG_SIZE;--55 //--87
-- constant UART_INTERCEPT_SEQ_SIZE_SIZE: Integer := 1;
-- constant UART_INTERCEPT_SEQ_ADD: Integer := UART_INTERCEPT_SEQ_SIZE_ADD+UART_INTERCEPT_SEQ_SIZE_SIZE;-- 56 //--88
-- constant UART_INTERCEPT_SEQ_SIZE: Integer := SEQUENCE_SIZE;
-- size of config
-- constant MAX_ADDRESS: Integer := UART_INTERCEPT_SEQ_ADD+UART_INTERCEPT_SEQ_SIZE;-- 64 //--96
constant LENGTH_DELAY: Integer := 4;
constant LENGTH_WIDTH: Integer := 4;
constant LENGTH_AMPLITUDE: Integer := 1;
constant LENGTH_TRIG_CONFS: Integer := LENGTH_DELAY + LENGTH_WIDTH;
constant MAX_ADDRESS: Integer := LENGTH_AMPLITUDE+LENGTH_TRIG_CONFS*NB_TRIGGERS;-- 64 //--96
type APDUHeader is array (0 to 3) of byte;
type APDUConf is
record
wait_counter: u32; -- define a timeout
header_select: APDUHeader;
header_select_en: std_logic;
end record;
type TrigConf is
record
trig_delay: unsigned(LENGTH_DELAY*8-1 downto 0);--wait before trig in and rising edge
trig_width: unsigned(LENGTH_WIDTH*8-1 downto 0);--trig up width
-- trig_amplitude: unsigned(LENGTH_AMPLITUDE*8-1 downto 0);--trig up width
end record;
type TrigConfs is array (0 to NB_TRIGGERS-1) of TrigConf;
type trig_delays is array (0 to NB_TRIGGERS-1) of unsigned(LENGTH_DELAY*8-1 downto 0);
type trig_widths is array (0 to NB_TRIGGERS-1) of unsigned(LENGTH_WIDTH*8-1 downto 0);
-- type pckt_directions is array (0 to NB_TRIGGERS-1) of unsigned(7 downto 0);
-- type UartSequence is array (0 to SEQUENCE_SIZE-1) of byte;
-- type UartTrigConf is
-- record
-- sequence: UartSequence;
-- sequence_size: u8;
-- end record;
end triggy_common;
......@@ -64,8 +64,6 @@ architecture behavior of triggy_top is
component configuration_manager is
port(clk: in std_logic;
reset: in std_logic;
-- memout: out std_logic_vector(MAX_ADDRESS*8-1 downto 0);
--fifo from Uart PC rx (cross clock domains)
din: in byte;
din_rdy: in std_logic;
......@@ -132,8 +130,6 @@ architecture behavior of triggy_top is
signal baud_clk: std_logic;
-- triggers
-- signal trig_starts: std_logic_vector(NB_TRIGGERS-1 downto 0);
-- signal triggers_buf: std_logic_vector(NB_TRIGGERS-1 downto 0);
signal trig_confs: TrigConfs;
signal reset: std_logic;
......@@ -149,12 +145,12 @@ begin
end if;
end process;
uart_conf_s<= (idle_polarity => '1',
baud_gen_step => X"04B7F5A5",-- To adapt with clk period -> 115200 bauds
start_bits => One,
stop_bits => One,
parity => None,
data_bits => Eight);
uart_conf_s<= (idle_polarity => '1',
baud_gen_step => X"04B7F5A5",-- To adapt with clk period -> 115200 bauds
start_bits => One,
stop_bits => One,
parity => None,
data_bits => Eight);
remplissage_trigconf : process(rst,trig_confs , clk_in)
begin
......@@ -237,10 +233,7 @@ end process;
tick_o => open
);
-- debug <= fifo_rx_dout;
-- BUFFER between PC Uart and config_manager: fifo + autoreaders
-- BUFFER between PC Uart and config_manager: fifo + autoreaders
pc_uart_rx_fifo: fifo
port map(
......
......@@ -32,7 +32,7 @@
<Option Name="EnableBDX" Val="FALSE"/>
<Option Name="DSAVendor" Val="xilinx"/>
<Option Name="DSANumComputeUnits" Val="60"/>
<Option Name="WTXSimLaunchSim" Val="29"/>
<Option Name="WTXSimLaunchSim" Val="51"/>
<Option Name="WTModelSimLaunchSim" Val="0"/>
<Option Name="WTQuestaLaunchSim" Val="0"/>
<Option Name="WTIesLaunchSim" Val="0"/>
......@@ -191,26 +191,57 @@
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PSRCDIR/sources_1/configuration_manager.vhd">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PSRCDIR/sources_1/fifo_autoreader.vhd">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PIPUSERFILESDIR/ip/fifo/fifo_sim_netlist.vhdl">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PSRCDIR/sim_1/new/config_manager_tb.vhd">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PSRCDIR/sources_1/PLL_clk_PbMUX.vhd">
<FileInfo>
<Attr Name="AutoDisabled" Val="1"/>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PSRCDIR/sim_1/new/traitor_tb.vhd">
<FileInfo>
<Attr Name="AutoDisabled" Val="1"/>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PSIMDIR/config_manager_tb_behav.wcfg">
<FileInfo>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<Config>
<Option Name="DesignMode" Val="RTL"/>
<Option Name="TopModule" Val="traitor_tb"/>
<Option Name="TopModule" Val="config_manager_tb"/>
<Option Name="TopLib" Val="xil_defaultlib"/>
<Option Name="TransportPathDelay" Val="0"/>
<Option Name="TransportIntDelay" Val="0"/>
<Option Name="SimMode" Val="post-synthesis"/>
<Option Name="SrcSet" Val=""/>
<Option Name="XSimWcfgFile" Val="$PSIMDIR/config_manager_tb_behav.wcfg"/>
<Option Name="NLNetlistMode" Val="funcsim"/>
</Config>
</FileSet>
......@@ -230,6 +261,7 @@
</File>
<File Path="$PSRCDIR/sources_1/ip/ila_0/ila_0.xci">
<FileInfo>
<Attr Name="AutoDisabled" Val="1"/>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
......@@ -277,9 +309,7 @@
</Run>
<Run Id="ila_0_synth_1" Type="Ft3:Synth" SrcSet="ila_0" Part="xc7a35tcsg324-1" ConstrsSet="ila_0" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/ila_0_synth_1" IncludeInArchive="true">
<Strategy Version="1" Minor="2">
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2018">
<Desc>Vivado Synthesis Defaults</Desc>
</StratHandle>
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2018"/>
<Step Id="synth_design"/>
</Strategy>
<GeneratedRun Dir="$PRUNDIR" File="gen_run.xml"/>
......@@ -307,9 +337,7 @@
</Run>
<Run Id="ila_0_impl_1" Type="Ft2:EntireDesign" Part="xc7a35tcsg324-1" ConstrsSet="ila_0" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="ila_0_synth_1" IncludeInArchive="false" GenFullBitstream="true">
<Strategy Version="1" Minor="2">
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2018">
<Desc>Default settings for Implementation.</Desc>
</StratHandle>
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2018"/>
<Step Id="init_design"/>
<Step Id="opt_design"/>
<Step Id="power_opt_design"/>
......
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