Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
X
x393_sata
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
x393_sata
Commits
36c295d8
Commit
36c295d8
authored
Mar 12, 2016
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
modified py393sata/ahci_fsm_sequence.py, rebuilt
parent
0ec9beab
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
109 additions
and
86 deletions
+109
-86
.project
.project
+17
-17
action_decoder.v
generated/action_decoder.v
+2
-2
condition_mux.v
generated/condition_mux.v
+2
-2
ahxi_fsm_code.vh
includes/ahxi_fsm_code.vh
+20
-19
org.eclipse.core.resources.prefs
py393sata/.settings/org.eclipse.core.resources.prefs
+1
-0
ahci_fsm_sequence.py
py393sata/ahci_fsm_sequence.py
+63
-38
system_defines.vh
system_defines.vh
+1
-1
tb_ahci.tf
tb/tb_ahci.tf
+2
-2
top.v
top.v
+1
-5
No files found.
.project
View file @
36c295d8
...
...
@@ -52,87 +52,87 @@
<link>
<name>
vivado_logs/VivadoBitstream.log
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoBitstream-2016031
1095400893
.log
</location>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoBitstream-2016031
2151407716
.log
</location>
</link>
<link>
<name>
vivado_logs/VivadoOpt.log
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoOpt-2016031
1095400893
.log
</location>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoOpt-2016031
2151407716
.log
</location>
</link>
<link>
<name>
vivado_logs/VivadoOptPhys.log
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoOptPhys-2016031
1095400893
.log
</location>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoOptPhys-2016031
2151407716
.log
</location>
</link>
<link>
<name>
vivado_logs/VivadoOptPower.log
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoOptPower-2016031
1095400893
.log
</location>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoOptPower-2016031
2151407716
.log
</location>
</link>
<link>
<name>
vivado_logs/VivadoPlace.log
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoPlace-2016031
1095400893
.log
</location>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoPlace-2016031
2151407716
.log
</location>
</link>
<link>
<name>
vivado_logs/VivadoRoute.log
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoRoute-2016031
1095400893
.log
</location>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoRoute-2016031
2151407716
.log
</location>
</link>
<link>
<name>
vivado_logs/VivadoSynthesis.log
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoSynthesis-2016031
1095237675
.log
</location>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoSynthesis-2016031
2151407716
.log
</location>
</link>
<link>
<name>
vivado_logs/VivadoTimimgSummaryReportImplemented.log
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportImplemented-2016031
1095400893
.log
</location>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportImplemented-2016031
2151407716
.log
</location>
</link>
<link>
<name>
vivado_logs/VivadoTimimgSummaryReportSynthesis.log
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportSynthesis-2016031
1095237675
.log
</location>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportSynthesis-2016031
2151407716
.log
</location>
</link>
<link>
<name>
vivado_logs/VivadoTimingReportImplemented.log
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportImplemented-2016031
1095400893
.log
</location>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportImplemented-2016031
2151407716
.log
</location>
</link>
<link>
<name>
vivado_logs/VivadoTimingReportSynthesis.log
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportSynthesis-2016031
1095237675
.log
</location>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportSynthesis-2016031
2151407716
.log
</location>
</link>
<link>
<name>
vivado_state/x393_sata-opt-phys.dcp
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-phys-2016031
1095400893
.dcp
</location>
<location>
/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-phys-2016031
2151407716
.dcp
</location>
</link>
<link>
<name>
vivado_state/x393_sata-opt-power.dcp
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-power-2016031
1095400893
.dcp
</location>
<location>
/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-power-2016031
2151407716
.dcp
</location>
</link>
<link>
<name>
vivado_state/x393_sata-opt.dcp
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-2016031
1095400893
.dcp
</location>
<location>
/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-2016031
2151407716
.dcp
</location>
</link>
<link>
<name>
vivado_state/x393_sata-place.dcp
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_state/x393_sata-place-2016031
1095400893
.dcp
</location>
<location>
/home/andrey/git/x393_sata/vivado_state/x393_sata-place-2016031
2151407716
.dcp
</location>
</link>
<link>
<name>
vivado_state/x393_sata-route.dcp
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_state/x393_sata-route-2016031
1095400893
.dcp
</location>
<location>
/home/andrey/git/x393_sata/vivado_state/x393_sata-route-2016031
2151407716
.dcp
</location>
</link>
<link>
<name>
vivado_state/x393_sata-synth.dcp
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_state/x393_sata-synth-2016031
1095237675
.dcp
</location>
<location>
/home/andrey/git/x393_sata/vivado_state/x393_sata-synth-2016031
2151407716
.dcp
</location>
</link>
</linkedResources>
</projectDescription>
generated/action_decoder.v
View file @
36c295d8
/*******************************************************************************
* Module: action_decoder
* Date:2016-03-
07
* Author: auto-generated file, see ahci_fsm_sequence.py
* Date:2016-03-
12
* Author: auto-generated file, see ahci_fsm_sequence
_old
.py
* Description: Decode sequencer code to 1-hot actions
*******************************************************************************/
...
...
generated/condition_mux.v
View file @
36c295d8
/*******************************************************************************
* Module: condition_mux
* Date:2016-03-
07
* Author: auto-generated file, see ahci_fsm_sequence.py
* Date:2016-03-
12
* Author: auto-generated file, see ahci_fsm_sequence
_old
.py
* Description: Select condition
*******************************************************************************/
...
...
includes/ahxi_fsm_code.vh
View file @
36c295d8
, .INIT_00 (256'h00100000000E0000000C02020035000000220000000C0000000A0000000C0000)
, .INIT_01 (256'h1C3B9448543244190060001B0108001B00500402040401040022000600120000)
, .INIT_02 (256'h001BC8300014000C0210002B2506250D0180001B0003004200180000001B4454)
, .INIT_03 (256'h44394C6A2C44141B0012003B01080028000A04080022001B01020110001B0005)
, .INIT_04 (256'h003B0210001B14480102005004020404003BB07F707C00A0003B8C6D845484C6)
, .INIT_05 (256'h045A000000502506250D0240004E2506250D0240005E0000003B0000001B0210)
, .INIT_06 (256'h903B02200204006D0402009000EDA89868FB18F418D398AF58DF388464560C27)
, .INIT_07 (256'h0000003BB07F0000005200840022003BB07F707C307930FB02080073D10D5103)
, .INIT_08 (256'h0096289029090000000000000014021000882506250D018000A1D1060120003B)
, .INIT_09 (256'h48810CB529090210009C2506250D04400052000C009600050096C89400220044)
, .INIT_0A (256'h024000520081005248AD00220044003B48AD28A929090000000000000024003B)
, .INIT_0B (256'h50C20044008800BDD1065103042000B9883B08A1003000B5021000B32506250D)
, .INIT_0C (256'h00440048021000CDC50D2506250600C000C80030003B88A100300009003B88A1)
, .INIT_0D (256'h0280003B34DA000000DC001100DCC8DA021000D72506250D0140003B88A150C2)
, .INIT_0E (256'h2506250D0480005201010052C8EB29090000000000000014021000E32506250D)
, .INIT_0F (256'h021000FF2506250D024001010082021000F82506250D0240003B0401021000F1)
, .INIT_10 (256'h003B00410410010B0000010B0201010B00210410010B00210084010100000101)
, .INITP_00 (256'h8220098170902401E272722222800309418810820809C8020188800222222222)
, .INITP_01 (256'h89C827209C828009C22089C680272181A01CB889C8605A00AA2722081A00270C)
, .INITP_02 (256'h0000000000000000000000000000000000000000000000000000000020888208)
, .INIT_01 (256'h1C3C9449543244190060001B0108001B00500402040401040022000600120000)
, .INIT_02 (256'h001BC8300014000C0210002B2507250E0180001B0003004200180000001B4455)
, .INIT_03 (256'h4C6B2C45141B0012003C01080028000A040800220410001B01020110001B0005)
, .INIT_04 (256'h0210001B14490102005004020404003CB080707D00A0003C8C6E845584C7443A)
, .INIT_05 (256'h000000512507250E0240004F2507250E0240005F0000003C0000001B0210003C)
, .INIT_06 (256'h02200204006E0402009000EEA89968FC18F518D498B058E0388564570C27045B)
, .INIT_07 (256'h003CB0800000005300840022003CB080707D307A30FC02080074D10E5104903C)
, .INIT_08 (256'h2891290A0000000000000014021000892507250E018000A2D1070120003C0000)
, .INIT_09 (256'h0CB6290A0210009D2507250E04400053000C009700050097C895002200440097)
, .INIT_0A (256'h00530081005348AE00220044003C48AE28AA290A0000000000000024003C4882)
, .INIT_0B (256'h0044008800BED1075104042000BA883C08A2003000B6021000B42507250E0240)
, .INIT_0C (256'h0048021000CEC50E2507250700C000C90030003C88A200300009003C88A250C3)
, .INIT_0D (256'h003C34DB000000DD001100DDC8DB021000D82507250E0140003C88A250C30044)
, .INIT_0E (256'h250E0480005301010053C8EC290A0000000000000014021000E42507250E0280)
, .INIT_0F (256'h01002507250E024001020082021000F92507250E0240003C0401021000F22507)
, .INIT_10 (256'h00410410010C0000010C0201010C00210410010C002100840102000001020210)
, .INIT_11 (256'h000000000000000000000000000000000000000000000000000000000000003C)
, .INITP_00 (256'h08802605C240900789C9C8888A000C25062040820809C8020188800222222222)
, .INITP_01 (256'h27209C82720A00270882271A009C86068072E22721816802A89C882068009C32)
, .INITP_02 (256'h0000000000000000000000000000000000000000000000000000000082220822)
py393sata/.settings/org.eclipse.core.resources.prefs
View file @
36c295d8
eclipse.preferences.version=1
encoding/ahci_fsm_sequence.py=utf-8
encoding/create_ahci_registers.py=utf-8
encoding/x393sata.py=utf-8
py393sata/ahci_fsm_sequence.py
View file @
36c295d8
...
...
@@ -42,6 +42,7 @@ condition_mux_verilog_path= '../generated/condition_mux.v'
condition_mux_module_name
=
'condition_mux'
condition_mux_fanout
=
8
code_rom_path
=
'../includes/ahxi_fsm_code.vh'
ahci_fsm_sequence_path
=
'../generated/ahci_fsm_sequence.lst'
#Set actions, conditions to empty string to rebuild list. Then edit order and put here
actions
=
[
'NOP'
,
# CTRL_STAT
...
...
@@ -723,6 +724,7 @@ while ln < len(sequence):
ln
+=
1
labels
=
{}
async_labels
=
set
()
jumps
=
set
()
for
ln
,
line
in
enumerate
(
sequence
):
if
LBL
in
line
:
...
...
@@ -731,6 +733,8 @@ for ln, line in enumerate(sequence):
print
(
"Duplicate label '
%
s': line #
%
d and line #
%
d"
%
(
label
,
labels
[
label
],
ln
))
else
:
labels
[
label
]
=
ln
if
ADDR
in
line
:
async_labels
.
add
(
label
)
if
GOTO
in
line
:
jumps
.
add
(
line
[
GOTO
])
...
...
@@ -749,30 +753,55 @@ if not conditions:
if
IF
in
line
:
if
not
line
[
IF
]
in
conditions
:
conditions
.
append
(
line
[
IF
])
listing
=
[]
listing
.
append
(
"Checking for undefined labels:"
)
print
(
"Checking for undefined labels:"
)
undef_jumps
=
[]
for
label
in
jumps
:
if
not
label
in
labels
:
undef_jumps
.
append
(
label
)
if
undef_jumps
:
print
(
"Undefined jumps:"
)
listing
.
append
(
"Undefined jumps:"
)
print
(
"Undefined jumps:"
)
for
i
,
jump
in
enumerate
(
undef_jumps
):
print
(
"
%
d: '
%
s'"
%
(
i
,
jump
))
listing
.
append
(
"
%
d: '
%
s'"
%
(
i
,
jump
))
print
(
"
%
d: '
%
s'"
%
(
i
,
jump
))
else
:
print
(
"All jumps are to defined labels"
)
print
(
"Checking for unused labels:"
)
listing
.
append
(
"All jumps are to the defined labels"
)
print
(
"All jumps are to the defined labels"
)
print
(
""
)
listing
.
append
(
""
)
print
(
"Checking for unused labels:"
)
listing
.
append
(
"Checking for unused labels:"
)
unused_labels
=
[]
for
label
in
labels
:
if
not
label
in
jumps
:
# print("label=%s, labels[label] = %s"%(label, str(labels[label])))
if
(
not
label
in
jumps
)
and
(
not
label
in
async_labels
):
unused_labels
.
append
(
label
)
if
unused_labels
:
print
(
"Unused labels:"
)
print
(
"Unused labels:"
)
listing
.
append
(
"Unused labels:"
)
for
i
,
label
in
enumerate
(
unused_labels
):
print
(
"
%
d: '
%
s'"
%
(
i
,
label
))
print
(
"
%
d: '
%
s'"
%
(
i
,
label
))
listing
.
append
(
"
%
d: '
%
s'"
%
(
i
,
label
))
else
:
print
(
"All labels are used"
)
print
(
"All labels are used"
)
listing
.
append
(
"All labels are used"
)
print
(
""
)
listing
.
append
(
""
)
if
async_labels
:
print
(
"Asynchronous transitions labels:"
)
listing
.
append
(
"Asynchronous transitions labels:"
)
async_entries
=
{}
for
label
in
async_labels
:
async_entries
[
labels
[
label
]]
=
label
for
k
in
sorted
(
async_entries
.
keys
()):
listing
.
append
(
"0x
%03
x:
%
s"
%
(
k
,
async_entries
[
k
]))
print
(
""
)
listing
.
append
(
""
)
wait_actions
=
[]
fast_actions
=
[]
for
a
in
actions
:
...
...
@@ -806,33 +835,28 @@ vals = bin_cnk (*conditions_cnk)
for
i
,
v
in
enumerate
(
conditions
):
condition_vals
[
v
]
=
vals
[
i
]
listing
.
append
(
"Number of lines :
%
d"
%
(
len
(
sequence
)))
listing
.
append
(
"Number of labels :
%
d"
%
(
len
(
labels
)))
listing
.
append
(
"Number of actions :
%
d"
%
(
len
(
actions
)))
listing
.
append
(
"Number of conditions :
%
d"
%
(
len
(
conditions
)))
print
(
"Number of lines :
%
d"
%
(
len
(
sequence
)))
print
(
"Number of labels :
%
d"
%
(
len
(
labels
)))
print
(
"Number of actions :
%
d"
%
(
len
(
actions
)))
print
(
"Number of conditions :
%
d"
%
(
len
(
conditions
)))
#print ("\nActions:")
#for i,a in enumerate(actions):
# print ("%02d: %s"%(i,a))
print
(
"
\n
Actions that do not wait for done (
%
d):"
%
(
len
(
fast_actions
)))
listing
.
append
(
"
\n
Actions that do not wait for done (
%
d):"
%
(
len
(
fast_actions
)))
for
i
,
a
in
enumerate
(
fast_actions
):
# print ("%02d: %s"%(i,a))
print
(
"
%
s"
%
(
a
))
print
(
"
\n
Actions that wait for done (
%
d):"
%
(
len
(
wait_actions
)))
listing
.
append
(
"
%
s"
%
(
a
))
listing
.
append
(
"
\n
Actions that wait for done (
%
d):"
%
(
len
(
wait_actions
)))
for
i
,
a
in
enumerate
(
wait_actions
):
# print ("%02d: %s"%(i,a))
print
(
"
%
s"
%
(
a
))
listing
.
append
(
"
%
s"
%
(
a
))
print
(
"
\n
Conditions(
%
d):"
%
(
len
(
conditions
)))
listing
.
append
(
"
\n
Conditions(
%
d):"
%
(
len
(
conditions
)))
for
i
,
c
in
enumerate
(
conditions
):
# print ("%02d: %s"%(i,c))
print
(
"
%
s"
%
(
c
))
listing
.
append
(
"
%
s"
%
(
c
))
#print ("action_vals=", action_vals)
#print ("condition_vals=",condition_vals)
#for i, line in enumerate(sequence):
# print ("%03x: %s"%(i,line))
if
not
action_decoder_verilog_path
:
action_decoder_verilog
(
actions
,
action_vals
,
action_decoder_module_name
)
...
...
@@ -850,25 +874,22 @@ else:
code
=
code_generator
(
sequence
,
action_vals
,
condition_vals
,
labels
)
#print_params(create_with_parity(code, 18, 0, False),os.path.abspath(os.path.join(os.path.dirname(__file__), code_rom_path)))
print_params
(
create_with_parity
(
code
,
18
,
False
),
os
.
path
.
abspath
(
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
code_rom_path
)))
print
(
"AHCI FSM code data is written to
%
s"
%
(
os
.
path
.
abspath
(
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
code_rom_path
))))
#longest_label = max([len(labels[l]) for l in labels.keys()])
longest_label
=
max
([
len
(
l
)
for
l
in
labels
])
longest_act
=
max
([
len
(
act
)
for
act
in
actions
])
longest_cond
=
max
([
len
(
cond
)
for
cond
in
conditions
])
format_act
=
"
%%%
ds do
%%
s
%%
s"
%
(
longest_label
+
1
)
format_cond
=
"
%%%
ds
%%%
ds goto
%%
s"
%
(
longest_label
+
1
,
longest_cond
+
3
)
#print ("format_act=", format_act)
#print ("format_cond=",format_cond)
print
(
"
\n
code:"
)
listing
.
append
(
"
\n
code:"
)
for
a
,
c
in
enumerate
(
code
):
l
=
sequence
[
a
]
if
LBL
in
l
:
print
()
print
(
"
%03
x:
%05
x #"
%
(
a
,
c
),
end
=
""
)
listing
.
append
(
""
)
# listing.append ("%03x: %05x #"%(a,c),end = "")
line_start
=
"
%03
x:
%05
x #"
%
(
a
,
c
)
if
(
ACT
in
l
)
or
(
LBL
in
l
):
try
:
lbl
=
l
[
LBL
]
+
":"
...
...
@@ -882,15 +903,19 @@ for a,c in enumerate(code):
if
act
.
endswith
(
'*'
):
wait
=
", WAIT DONE"
act
=
act
[
0
:
-
1
]
print
(
format_act
%
(
lbl
,
act
,
wait
))
listing
.
append
(
line_start
+
(
format_act
%
(
lbl
,
act
,
wait
)
))
else
:
try
:
cond
=
"if "
+
l
[
IF
]
except
:
cond
=
"always"
cond
+=
' '
*
(
longest_cond
+
3
-
len
(
cond
))
print
(
format_cond
%
(
""
,
cond
,
l
[
GOTO
]))
# print ("%03x: %05x # %s"%(a,c,str(sequence[a])))
listing
.
append
(
line_start
+
(
format_cond
%
(
""
,
cond
,
l
[
GOTO
])))
with
open
(
os
.
path
.
abspath
(
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
ahci_fsm_sequence_path
)),
"w"
)
as
lst_file
:
print
(
"This file is auto-generated by
%
s
\n\n
"
%
(
os
.
path
.
basename
(
__file__
)),
file
=
lst_file
)
for
l
in
listing
:
print
(
l
,
file
=
lst_file
)
#condition_mux_verilog(conditions, condition_vals, 'condition_mux',100, file=None
)
print
(
"AHCI FSM listing is written to
%
s"
%
(
os
.
path
.
abspath
(
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
ahci_fsm_sequence_path
)))
)
\ No newline at end of file
system_defines.vh
View file @
36c295d8
...
...
@@ -7,7 +7,7 @@
`define USE_DATASCOPE
// `define DATASCOPE_INCOMING_RAW
`define PRELOAD_BRAMS
`define AHCI_SATA 1
//
`define AHCI_SATA 1
`define DEBUG_ELASTIC
// Enviroment-dependent options
`ifdef IVERILOG
...
...
tb/tb_ahci.tf
View file @
36c295d8
...
...
@@ -72,8 +72,8 @@ reg [31:0] TESTBENCH_DATA;
reg [11:0] TESTBENCH_ID;
reg [639:0] DEVICE_TITLE = '
bz
;
// to show human-readable state in the GTKWave
reg
[
31
:
0
]
DEVICE_DATA
;
reg
[
11
:
0
]
Device_ID
;
///
reg [31:0] DEVICE_DATA;
///
reg [11:0] Device_ID;
initial
#1 $display("HI THERE");
initial
...
...
top.v
View file @
36c295d8
...
...
@@ -40,7 +40,7 @@
`include
"system_defines.vh"
module
top
#(
`include
"includes/x393_parameters.vh"
// SuppressThisWarning VEditor - partially used
//
`include "includes/x393_parameters.vh" // SuppressThisWarning VEditor - partially used
)
(
// sata serial data iface
...
...
@@ -164,11 +164,7 @@ axi_hp_clk #(
.
clk_axihp
(
hclk
)
,
// output
.
locked_axihp
()
// output // not controlled?
)
;
`ifdef
AHCI_SATA
sata_ahci_top
sata_top
(
`else
sata_top
sata_top
(
`endif
.
sata_clk
(
sclk
)
,
// reliable clock to source drp and cpll lock det circuits
.
reliable_clk
(
axi_aclk0
)
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment