Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
E
EtherBone Core
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Wiki
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Projects
EtherBone Core
Commits
80e84385
Commit
80e84385
authored
13 years ago
by
Mathias Kreider
Browse files
Options
Downloads
Patches
Plain Diff
No commit message
No commit message
parent
e7828d6f
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
hdl/EB_SPEC_Test/EB_2_wb_converter.vhd
+7
-14
7 additions, 14 deletions
hdl/EB_SPEC_Test/EB_2_wb_converter.vhd
hdl/EB_SPEC_Test/EB_RX_CTRL.vhd
+109
-78
109 additions, 78 deletions
hdl/EB_SPEC_Test/EB_RX_CTRL.vhd
hdl/EB_SPEC_Test/EB_TX_CTRL.vhd
+115
-97
115 additions, 97 deletions
hdl/EB_SPEC_Test/EB_TX_CTRL.vhd
with
231 additions
and
189 deletions
hdl/EB_SPEC_Test/EB_2_wb_converter.vhd
+
7
−
14
View file @
80e84385
...
@@ -435,15 +435,12 @@ begin
...
@@ -435,15 +435,12 @@ begin
report
"EB: MALFORMED PACKET"
severity
note
;
report
"EB: MALFORMED PACKET"
severity
note
;
else
else
--eb hdr seems valid, prepare answering packet. Prefill RX buffer
--eb hdr seems valid, prepare answering packet. Prefill RX buffer
if
(
unsigned
(
s_rx_fifo_gauge
)
>
3
)
then
s_state_TX
<=
EB_HDR_INIT
;
s_state_RX
<=
CYC_HDR_REC
;
s_state_TX
<=
EB_HDR_INIT
;
else
--report "EB: Waiting for buffer ..." severity note;
end
if
;
if
(
s_EB_RX_HDR
.
PROBE
=
'1'
)
then
-- no probe, prepare cycle reception
if
(
s_EB_RX_HDR
.
PROBE
=
'1'
)
then
-- no probe, prepare cycle reception
s_state_RX
<=
EB_HDR_PROBE_ID
;
s_state_RX
<=
EB_HDR_PROBE_ID
;
s_state_TX
<=
EB_HDR_INIT
;
else
s_state_RX
<=
CYC_HDR_REC
;
end
if
;
end
if
;
end
if
;
end
if
;
...
@@ -492,7 +489,7 @@ begin
...
@@ -492,7 +489,7 @@ begin
end
if
;
end
if
;
when
CYC_HDR_READ_GET_ADR
=>
if
(
s_rx_fifo_
am_
empty
=
'0'
)
then
when
CYC_HDR_READ_GET_ADR
=>
if
(
s_rx_fifo_empty
=
'0'
)
then
s_state_RX
<=
WB_READ_RDY
;
s_state_RX
<=
WB_READ_RDY
;
end
if
;
end
if
;
...
@@ -527,11 +524,7 @@ begin
...
@@ -527,11 +524,7 @@ begin
when
ERROR
=>
s_state_TX
<=
IDLE
;
when
ERROR
=>
s_state_TX
<=
IDLE
;
s_state_RX
<=
IDLE
;
s_state_RX
<=
IDLE
;
if
((
s_EB_RX_HDR
.
VER
/=
c_EB_VER
)
-- wrong version
OR
(
s_EB_RX_HDR
.
ADDR_SIZE
/=
c_MY_EB_ADDR_SIZE
)
-- wrong size
OR
(
s_EB_RX_HDR
.
PORT_SIZE
/=
c_MY_EB_PORT_SIZE
))
then
s_state_TX
<=
ERROR
;
end
if
;
when
others
=>
s_state_RX
<=
IDLE
;
when
others
=>
s_state_RX
<=
IDLE
;
end
case
;
end
case
;
...
...
This diff is collapsed.
Click to expand it.
hdl/EB_SPEC_Test/EB_RX_CTRL.vhd
+
109
−
78
View file @
80e84385
...
@@ -165,7 +165,8 @@ signal RX_HDR_slv : std_logic_vector(c_IPV4_HLEN*8-1 downto 0) ;
...
@@ -165,7 +165,8 @@ signal RX_HDR_slv : std_logic_vector(c_IPV4_HLEN*8-1 downto 0) ;
--shift register input and control signals
--shift register input and control signals
signal
byte_count
:
natural
range
0
to
1600
;
signal
byte_count
:
natural
range
0
to
1600
;
signal
counter_comp
:
natural
range
0
to
1600
;
signal
counter_comp
:
natural
range
0
to
1600
;
signal
s_timeout_cnt
:
unsigned
(
14
downto
0
);
alias
a_timeout
:
unsigned
(
0
downto
0
)
is
s_timeout_cnt
(
s_timeout_cnt
'left
downto
s_timeout_cnt
'left
);
signal
eop
:
natural
range
0
to
1600
;
signal
eop
:
natural
range
0
to
1600
;
...
@@ -296,8 +297,21 @@ begin
...
@@ -296,8 +297,21 @@ begin
end
if
;
end
if
;
end
process
;
end
process
;
timeout
:
process
(
clk_i
)
begin
if
rising_edge
(
clk_i
)
then
--Counter: Timeout
-- reset timeout if idle
if
((
nRST_i
=
'0'
)
or
(
state
=
IDLE
))
then
--s_timeout_cnt <= (others => '1');
s_timeout_cnt
<=
to_unsigned
(
5000
,
s_timeout_cnt
'length
);
else
s_timeout_cnt
<=
s_timeout_cnt
-1
;
end
if
;
end
if
;
end
process
;
...
@@ -427,21 +441,24 @@ begin
...
@@ -427,21 +441,24 @@ begin
--
--
when
chk
=>
parser_wait
<=
'1'
;
when
chk
=>
parser_wait
<=
'1'
;
if
((
IPV4_RX
.
DST
=
my_ip_i
or
IPV4_RX
.
DST
=
c_BROADCAST_IP
)
and
IPV4_RX
.
PRO
=
c_PRO_UDP
)
then
if
(
IPV4_RX
.
PRO
=
c_PRO_UDP
)
then
if
(
UDP_RX
.
DST_PORT
=
my_port_i
)
then
--if((IPV4_RX.DST = my_ip_i) or (IPV4_RX.DST = c_BROADCAST_IP)) then
report
(
"RX: hdr parsed successfully, handing over payload ..."
)
severity
note
;
if
(
UDP_RX
.
DST_PORT
=
my_port_i
)
then
parse
<=
done
;
report
(
"RX: hdr parsed successfully, handing over payload ..."
)
severity
note
;
parse
<=
done
;
else
report
(
"RX: wrong port"
)
severity
warning
;
else
parse
<=
errors
;
report
(
"RX: wrong port"
)
severity
warning
;
end
if
;
parse
<=
errors
;
else
end
if
;
report
(
"RX: not addressed to my IP"
)
severity
warning
;
--else
-- report("RX: not addressed to my IP") severity warning;
-- parse <= errors;
-- parse <= errors;
--parse <= errors;
--end if;
parse
<=
done
;
else
end
if
;
report
(
"RX: Non UDP packet"
)
severity
warning
;
parse
<=
errors
;
end
if
;
when
done
=>
--parser_wait <= '1';
when
done
=>
--parser_wait <= '1';
valid_o
<=
'1'
;
valid_o
<=
'1'
;
if
(
parser_reset
=
'1'
)
then
if
(
parser_reset
=
'1'
)
then
...
@@ -466,71 +483,85 @@ begin
...
@@ -466,71 +483,85 @@ begin
state
<=
IDLE
;
state
<=
IDLE
;
else
else
snk_hdr_fsm_STALL
<=
'0'
;
--no timeout? Good, run FSM
parser_reset
<=
'0'
;
if
(
a_timeout
=
"0"
)
then
case
state
is
snk_hdr_fsm_STALL
<=
'0'
;
parser_reset
<=
'0'
;
case
state
is
when
IDLE
=>
if
(
snk_i
.
cyc
=
'1'
AND
snk_i
.
adr
=
c_WRF_DATA
)
then
--snk_hdr_fsm_STALL <= '0';
state
<=
HEADER
;
end
if
;
when
HEADER
=>
if
(
snk_i
.
cyc
=
'0'
)
then
report
(
"Header was aborted"
)
severity
warning
;
state
<=
ERRORS
;
else
if
(
parse
=
DONE
)
then
eop
<=
(
counter_comp
+
to_integer
(
unsigned
(
IPV4_RX
.
IHL
)
*
4
)
+
to_integer
(
unsigned
(
UDP_RX
.
MLEN
))
-2
);
state
<=
PAYLOAD
;
--snk_hdr_fsm_STALL <= '1';
else
if
(
snk_i
.
cyc
=
'0'
)
then
report
(
"RX: packet hdr aborted"
)
severity
warning
;
state
<=
ERRORS
;
end
if
;
if
(
parse
=
errors
)
then
report
(
"Not a valid Eth frame"
)
severity
warning
;
state
<=
ERRORS
;
end
if
;
end
if
;
end
if
;
when
PAYLOAD
=>
if
(
byte_count
<
c_ETH_FRAME_MIN_END
)
then
when
IDLE
=>
if
(
snk_i
.
cyc
=
'1'
AND
snk_i
.
adr
=
c_WRF_DATA
)
then
--snk_hdr_fsm_STALL <= '0';
state
<=
HEADER
;
end
if
;
when
HEADER
=>
if
(
snk_i
.
cyc
=
'0'
)
then
report
(
"Header was aborted"
)
severity
warning
;
state
<=
ERRORS
;
else
if
(
parse
=
DONE
)
then
eop
<=
(
counter_comp
+
to_integer
(
unsigned
(
IPV4_RX
.
IHL
)
*
4
)
+
to_integer
(
unsigned
(
UDP_RX
.
MLEN
))
-2
);
state
<=
PAYLOAD
;
--snk_hdr_fsm_STALL <= '1';
else
if
(
snk_i
.
cyc
=
'0'
)
then
report
(
"RX: packet hdr aborted"
)
severity
warning
;
state
<=
ERRORS
;
end
if
;
if
(
parse
=
errors
)
then
report
(
"Not a valid Eth frame"
)
severity
warning
;
state
<=
ERRORS
;
end
if
;
end
if
;
end
if
;
when
PAYLOAD
=>
if
(
byte_count
<
c_ETH_FRAME_MIN_END
)
then
if
(
snk_i
.
cyc
=
'0'
)
then
if
(
snk_i
.
cyc
=
'0'
)
then
report
(
"RX: runt frame (< 64)"
)
severity
warning
;
state
<=
ERRORS
;
report
(
"RX: runt frame (< 64)"
)
severity
warning
;
state
<=
ERRORS
;
elsif
(
byte_count
=
eop
AND
snk_i
.
STB
=
'1'
AND
snk_payload_conv
.
stall
=
'0'
)
then
elsif
(
byte_count
=
eop
AND
snk_i
.
STB
=
'1'
AND
snk_payload_conv
.
stall
=
'0'
)
then
state
<=
PADDING
;
state
<=
PADDING
;
end
if
;
else
if
(
byte_count
=
eop
AND
snk_i
.
STB
=
'1'
AND
snk_payload_conv
.
stall
=
'0'
)
then
state
<=
DONE
;
--elsif(byte_count > eop AND ) then
-- report("RX: frame too long") severity warning; state <= ERRORS;
-- else
-- report("RX: frame cut short") severity warning; state <= ERRORS;
end
if
;
end
if
;
else
--end if;
if
(
byte_count
=
eop
AND
snk_i
.
STB
=
'1'
AND
snk_payload_conv
.
stall
=
'0'
)
then
state
<=
DONE
;
--elsif(byte_count > eop AND ) then
-- report("RX: frame too long") severity warning; state <= ERRORS;
-- else
-- report("RX: frame cut short") severity warning; state <= ERRORS;
end
if
;
--end if;
end
if
;
end
if
;
when
PADDING
=>
if
(
snk_i
.
cyc
=
'0'
)
then
if
(
byte_count
=
c_ETH_FRAME_MIN_END
+
2
)
then
state
<=
DONE
;
when
PADDING
=>
if
(
snk_i
.
cyc
=
'0'
)
then
elsif
(
byte_count
>
c_ETH_FRAME_MIN_END
+
2
)
then
if
(
byte_count
=
c_ETH_FRAME_MIN_END
+
2
)
then
report
(
"RX: frame too long"
)
severity
warning
;
state
<=
ERRORS
;
state
<=
DONE
;
else
elsif
(
byte_count
>
c_ETH_FRAME_MIN_END
+
2
)
then
report
(
"RX: frame cut short"
)
severity
warning
;
state
<=
ERRORS
;
report
(
"RX: frame too long"
)
severity
warning
;
end
if
;
state
<=
ERRORS
;
end
if
;
else
when
DONE
=>
if
(
snk_i
.
cyc
=
'0'
)
then
report
(
"RX: frame cut short"
)
severity
warning
;
parser_reset
<=
'1'
;
state
<=
IDLE
;
state
<=
ERRORS
;
end
if
;
end
if
;
end
if
;
when
ERRORS
=>
parser_reset
<=
'1'
;
state
<=
IDLE
;
when
DONE
=>
if
(
snk_i
.
cyc
=
'0'
)
then
when
others
=>
parser_reset
<=
'1'
;
state
<=
IDLE
;
parser_reset
<=
'1'
;
state
<=
IDLE
;
end
case
;
end
if
;
when
ERRORS
=>
if
(
snk_i
.
cyc
=
'0'
)
then
parser_reset
<=
'1'
;
state
<=
IDLE
;
end
if
;
when
others
=>
parser_reset
<=
'1'
;
state
<=
IDLE
;
end
case
;
else
--timeout. something went seriously wrong, reset
parser_reset
<=
'1'
;
state
<=
IDLE
;
end
if
;
end
if
;
end
if
;
end
if
;
end
if
;
end
process
;
end
process
;
...
...
This diff is collapsed.
Click to expand it.
hdl/EB_SPEC_Test/EB_TX_CTRL.vhd
+
115
−
97
View file @
80e84385
...
@@ -159,6 +159,8 @@ signal TX_HDR_slv : std_logic_vector(c_IPV4_HLEN*8 -1 downto 0);
...
@@ -159,6 +159,8 @@ signal TX_HDR_slv : std_logic_vector(c_IPV4_HLEN*8 -1 downto 0);
--shift register output and control signals
--shift register output and control signals
signal
byte_count
:
natural
range
0
to
1600
;
signal
byte_count
:
natural
range
0
to
1600
;
signal
counter_comp
:
natural
range
0
to
1600
;
signal
counter_comp
:
natural
range
0
to
1600
;
signal
s_timeout_cnt
:
unsigned
(
14
downto
0
);
alias
a_timeout
:
unsigned
(
0
downto
0
)
is
s_timeout_cnt
(
s_timeout_cnt
'left
downto
s_timeout_cnt
'left
);
...
@@ -333,6 +335,20 @@ uut: WB_bus_adapter_streaming_sg generic map ( g_adr_width_A => 32,
...
@@ -333,6 +335,20 @@ uut: WB_bus_adapter_streaming_sg generic map ( g_adr_width_A => 32,
timeout
:
process
(
clk_i
)
begin
if
rising_edge
(
clk_i
)
then
--Counter: Timeout
-- reset timeout if idle
if
((
nRST_i
=
'0'
)
or
(
state
=
IDLE
))
then
--s_timeout_cnt <= (others => '1');
s_timeout_cnt
<=
to_unsigned
(
5000
,
s_timeout_cnt
'length
);
else
s_timeout_cnt
<=
s_timeout_cnt
-1
;
end
if
;
end
if
;
end
process
;
main_fsm
:
process
(
clk_i
)
main_fsm
:
process
(
clk_i
)
...
@@ -376,111 +392,113 @@ begin
...
@@ -376,111 +392,113 @@ begin
else
else
if
(
a_timeout
=
"0"
)
then
ld_hdr
<=
'0'
;
ld_hdr
<=
'0'
;
sh_hdr_en
<=
'0'
;
sh_hdr_en
<=
'0'
;
ld_p_chk_vals
<=
'0'
;
sh_chk_en
<=
'0'
;
calc_chk_en
<=
'0'
;
case
state
is
when
IDLE
=>
state_mux
<=
NONE
;
if
(
valid_i
=
'1'
)
then
ETH_TX
.
DST
<=
reply_MAC_i
;
IPV4_TX
.
DST
<=
reply_IP_i
;
IPV4_TX
.
TOL
<=
TOL_i
;
UDP_TX
.
MLEN
<=
payload_len_i
;
UDP_TX
.
DST_PORT
<=
reply_PORT_i
;
ld_p_chk_vals
<=
'1'
;
state
<=
CALC_CHKSUM
;
end
if
;
when
CALC_CHKSUM
=>
if
(
chksum_empty
=
'0'
)
then
ld_p_chk_vals
<=
'0'
;
sh_chk_en
<=
'1'
;
sh_chk_en
<=
'0'
;
calc_chk_en
<=
'1'
;
calc_chk_en
<=
'0'
;
else
if
(
chksum_done
=
'1'
)
then
IPV4_TX
.
SUM
<=
IP_chk_sum
;
ld_hdr
<=
'1'
;
state
<=
WAIT_SEND_REQ
;
end
if
;
end
if
;
when
WAIT_SEND_REQ
=>
if
(
wb_slave_i
.
CYC
=
'1'
)
then
case
state
is
when
IDLE
=>
state_mux
<=
NONE
;
state
<=
PREP_ETH
;
state_mux
<=
HEADER
;
if
(
valid_i
=
'1'
)
then
ETH_TX
.
DST
<=
reply_MAC_i
;
IPV4_TX
.
DST
<=
reply_IP_i
;
IPV4_TX
.
TOL
<=
TOL_i
;
UDP_TX
.
MLEN
<=
payload_len_i
;
UDP_TX
.
DST_PORT
<=
reply_PORT_i
;
ld_p_chk_vals
<=
'1'
;
state
<=
CALC_CHKSUM
;
end
if
;
when
CALC_CHKSUM
=>
if
(
chksum_empty
=
'0'
)
then
sh_chk_en
<=
'1'
;
calc_chk_en
<=
'1'
;
else
if
(
chksum_done
=
'1'
)
then
IPV4_TX
.
SUM
<=
IP_chk_sum
;
ld_hdr
<=
'1'
;
state
<=
WAIT_SEND_REQ
;
end
if
;
end
if
;
when
WAIT_SEND_REQ
=>
if
(
wb_slave_i
.
CYC
=
'1'
)
then
state
<=
PREP_ETH
;
state_mux
<=
HEADER
;
end
if
;
when
PREP_ETH
=>
TX_HDR_slv
(
TX_HDR_slv
'left
downto
TX_HDR_slv
'length
-
c_ETH_HLEN
*
8
)
<=
to_std_logic_vector
(
ETH_TX
);
s_ETH_end
<=
c_ETH_HLEN
-2
;
ld_hdr
<=
'1'
;
state
<=
ETH
;
when
ETH
=>
s_src_hdr_o
.
stb
<=
'1'
;
if
(
byte_count
=
s_ETH_end
and
src_i
.
stall
=
'0'
)
then
TX_HDR_slv
<=
to_std_logic_vector
(
IPV4_TX
);
ld_hdr
<=
'1'
;
state
<=
IPV4
;
s_src_hdr_o
.
stb
<=
'0'
;
end
if
;
end
if
;
when
IPV4
=>
s_src_hdr_o
.
stb
<=
'1'
;
when
PREP_ETH
=>
if
((
byte_count
=
(
s_ETH_end
+
c_IPV4_HLEN
))
and
src_i
.
stall
=
'0'
)
then
TX_HDR_slv
(
TX_HDR_slv
'left
downto
TX_HDR_slv
'length
-
c_ETH_HLEN
*
8
)
<=
to_std_logic_vector
(
ETH_TX
);
TX_HDR_slv
(
TX_HDR_slv
'left
downto
TX_HDR_slv
'length
-
c_UDP_HLEN
*
8
)
<=
to_std_logic_vector
(
UDP_TX
);
s_ETH_end
<=
c_ETH_HLEN
-2
;
ld_hdr
<=
'1'
;
ld_hdr
<=
'1'
;
state
<=
UDP
;
state
<=
ETH
;
s_src_hdr_o
.
stb
<=
'0'
;
end
if
;
when
ETH
=>
s_src_hdr_o
.
stb
<=
'1'
;
when
UDP
=>
s_src_hdr_o
.
stb
<=
'1'
;
if
(
byte_count
=
s_ETH_end
and
src_i
.
stall
=
'0'
)
then
if
(
byte_count
=
(
s_ETH_end
+
c_IPV4_HLEN
+
c_UDP_HLEN
)
and
src_i
.
stall
=
'0'
)
then
TX_HDR_slv
<=
to_std_logic_vector
(
IPV4_TX
);
state
<=
HDR_SEND
;
ld_hdr
<=
'1'
;
s_src_hdr_o
.
stb
<=
'0'
;
state
<=
IPV4
;
end
if
;
s_src_hdr_o
.
stb
<=
'0'
;
end
if
;
when
HDR_SEND
=>
state_mux
<=
PAYLOAD
;
state
<=
PAYLOAD_SEND
;
when
IPV4
=>
s_src_hdr_o
.
stb
<=
'1'
;
if
((
byte_count
=
(
s_ETH_end
+
c_IPV4_HLEN
))
and
src_i
.
stall
=
'0'
)
then
TX_HDR_slv
(
TX_HDR_slv
'left
downto
TX_HDR_slv
'length
-
c_UDP_HLEN
*
8
)
<=
to_std_logic_vector
(
UDP_TX
);
when
PAYLOAD_SEND
=>
if
(
s_src_payload_o
.
cyc
=
'0'
)
then
ld_hdr
<=
'1'
;
if
(
byte_count
<
c_ETH_FRAME_MIN_END
)
then
state
<=
UDP
;
state
<=
PADDING
;
s_src_hdr_o
.
stb
<=
'0'
;
state_mux
<=
PADDING
;
end
if
;
else
state
<=
WAIT_IFGAP
;
when
UDP
=>
s_src_hdr_o
.
stb
<=
'1'
;
state_mux
<=
NONE
;
if
(
byte_count
=
(
s_ETH_end
+
c_IPV4_HLEN
+
c_UDP_HLEN
)
and
src_i
.
stall
=
'0'
)
then
end
if
;
state
<=
HDR_SEND
;
end
if
;
s_src_hdr_o
.
stb
<=
'0'
;
end
if
;
when
PADDING
=>
s_src_padding_o
.
stb
<=
'1'
;
if
((
byte_count
=
c_ETH_FRAME_MIN_END
)
and
src_i
.
stall
=
'0'
)
then
when
HDR_SEND
=>
state_mux
<=
PAYLOAD
;
s_src_padding_o
.
stb
<=
'0'
;
state
<=
PAYLOAD_SEND
;
state
<=
WAIT_IFGAP
;
state_mux
<=
NONE
;
when
PAYLOAD_SEND
=>
if
(
s_src_payload_o
.
cyc
=
'0'
)
then
if
(
byte_count
<
c_ETH_FRAME_MIN_END
)
then
state
<=
PADDING
;
state_mux
<=
PADDING
;
else
state
<=
WAIT_IFGAP
;
state_mux
<=
NONE
;
end
if
;
end
if
;
end
if
;
when
WAIT_IFGAP
=>
--ensure interframe gap
--if(counter_ouput < 10) then
-- counter_ouput <= counter_ouput +1;
--else
state
<=
IDLE
;
--end if;
when
others
=>
state
<=
IDLE
;
when
PADDING
=>
s_src_padding_o
.
stb
<=
'1'
;
if
((
byte_count
=
c_ETH_FRAME_MIN_END
)
and
src_i
.
stall
=
'0'
)
then
s_src_padding_o
.
stb
<=
'0'
;
state
<=
WAIT_IFGAP
;
state_mux
<=
NONE
;
end
if
;
when
WAIT_IFGAP
=>
--ensure interframe gap
end
case
;
--if(counter_ouput < 10) then
-- counter_ouput <= counter_ouput +1;
--else
state
<=
IDLE
;
--end if;
when
others
=>
state
<=
IDLE
;
end
case
;
else
state
<=
IDLE
;
end
if
;
end
if
;
end
if
;
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment