Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
W
White Rabbit core collection
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
30
Issues
30
List
Board
Labels
Milestones
Merge Requests
2
Merge Requests
2
CI / CD
CI / CD
Pipelines
Schedules
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
White Rabbit core collection
Commits
558b636f
Commit
558b636f
authored
Jan 16, 2014
by
Maciej Lipinski
Committed by
Grzegorz Daniluk
Feb 04, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added a module to enable hw-generation of test streams at full load
parent
7760c768
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
464 additions
and
47 deletions
+464
-47
Manifest.py
modules/wr_endpoint/Manifest.py
+1
-0
endpoint_private_pkg.vhd
modules/wr_endpoint/endpoint_private_pkg.vhd
+20
-0
ep_registers_pkg.vhd
modules/wr_endpoint/ep_registers_pkg.vhd
+31
-3
ep_tx_inject_ctrl.vhd
modules/wr_endpoint/ep_tx_inject_ctrl.vhd
+201
-0
ep_tx_packet_injection.vhd
modules/wr_endpoint/ep_tx_packet_injection.vhd
+18
-10
ep_tx_path.vhd
modules/wr_endpoint/ep_tx_path.vhd
+87
-29
ep_wishbone_controller.vhd
modules/wr_endpoint/ep_wishbone_controller.vhd
+48
-4
ep_wishbone_controller.wb
modules/wr_endpoint/ep_wishbone_controller.wb
+45
-1
endpoint_regs.v
sim/endpoint_regs.v
+13
-0
No files found.
modules/wr_endpoint/Manifest.py
View file @
558b636f
...
@@ -34,6 +34,7 @@ files = [ "endpoint_private_pkg.vhd",
...
@@ -34,6 +34,7 @@ files = [ "endpoint_private_pkg.vhd",
"ep_wishbone_controller.vhd"
,
"ep_wishbone_controller.vhd"
,
"ep_registers_pkg.vhd"
,
"ep_registers_pkg.vhd"
,
"ep_crc32_pkg.vhd"
,
"ep_crc32_pkg.vhd"
,
"ep_tx_inject_ctrl.vhd"
,
"endpoint_pkg.vhd"
,
"endpoint_pkg.vhd"
,
"wr_endpoint.vhd"
,
"wr_endpoint.vhd"
,
"xwr_endpoint.vhd"
"xwr_endpoint.vhd"
...
...
modules/wr_endpoint/endpoint_private_pkg.vhd
View file @
558b636f
...
@@ -379,6 +379,26 @@ package endpoint_private_pkg is
...
@@ -379,6 +379,26 @@ package endpoint_private_pkg is
dbg_o
:
out
std_logic_vector
(
2
downto
0
));
dbg_o
:
out
std_logic_vector
(
2
downto
0
));
end
component
;
end
component
;
component
ep_tx_inject_ctrl
generic
(
g_min_if_gap_length
:
integer
);
port
(
clk_sys_i
:
in
std_logic
;
rst_n_i
:
in
std_logic
;
snk_fab_i
:
in
t_ep_internal_fabric
;
snk_dreq_o
:
out
std_logic
;
src_fab_o
:
out
t_ep_internal_fabric
;
src_dreq_i
:
in
std_logic
;
inject_req_o
:
out
std_logic
;
inject_ready_i
:
in
std_logic
;
inject_packet_sel_o
:
out
std_logic_vector
(
2
downto
0
);
inject_user_value_o
:
out
std_logic_vector
(
15
downto
0
);
inject_ctr_ena_o
:
out
std_logic
;
regs_i
:
in
t_ep_out_registers
);
end
component
;
procedure
f_pack_fifo_contents
(
procedure
f_pack_fifo_contents
(
signal
fab
:
in
t_ep_internal_fabric
;
signal
fab
:
in
t_ep_internal_fabric
;
signal
dout
:
out
std_logic_vector
;
signal
dout
:
out
std_logic_vector
;
...
...
modules/wr_endpoint/ep_registers_pkg.vhd
View file @
558b636f
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
---------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------
-- File : ep_registers_pkg.vhd
-- File : ep_registers_pkg.vhd
-- Author : auto-generated by wbgen2 from ep_wishbone_controller.wb
-- Author : auto-generated by wbgen2 from ep_wishbone_controller.wb
-- Created :
Fri Mar 15 17:03:12 2013
-- Created :
Thu Jan 16 14:57:37 2014
-- Standard : VHDL'87
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE ep_wishbone_controller.wb
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE ep_wishbone_controller.wb
...
@@ -35,6 +35,10 @@ package ep_wbgen2_pkg is
...
@@ -35,6 +35,10 @@ package ep_wbgen2_pkg is
dmcr_n_avg_i
:
std_logic_vector
(
11
downto
0
);
dmcr_n_avg_i
:
std_logic_vector
(
11
downto
0
);
dmsr_ps_val_i
:
std_logic_vector
(
23
downto
0
);
dmsr_ps_val_i
:
std_logic_vector
(
23
downto
0
);
dmsr_ps_rdy_i
:
std_logic
;
dmsr_ps_rdy_i
:
std_logic
;
inj_ctrl_pic_conf_ifg_i
:
std_logic_vector
(
15
downto
0
);
inj_ctrl_pic_conf_sel_i
:
std_logic_vector
(
2
downto
0
);
inj_ctrl_pic_valid_i
:
std_logic
;
inj_ctrl_pic_ena_i
:
std_logic
;
end
record
;
end
record
;
constant
c_ep_in_registers_init_value
:
t_ep_in_registers
:
=
(
constant
c_ep_in_registers_init_value
:
t_ep_in_registers
:
=
(
...
@@ -52,7 +56,11 @@ package ep_wbgen2_pkg is
...
@@ -52,7 +56,11 @@ package ep_wbgen2_pkg is
dmcr_en_i
=>
'0'
,
dmcr_en_i
=>
'0'
,
dmcr_n_avg_i
=>
(
others
=>
'0'
),
dmcr_n_avg_i
=>
(
others
=>
'0'
),
dmsr_ps_val_i
=>
(
others
=>
'0'
),
dmsr_ps_val_i
=>
(
others
=>
'0'
),
dmsr_ps_rdy_i
=>
'0'
dmsr_ps_rdy_i
=>
'0'
,
inj_ctrl_pic_conf_ifg_i
=>
(
others
=>
'0'
),
inj_ctrl_pic_conf_sel_i
=>
(
others
=>
'0'
),
inj_ctrl_pic_valid_i
=>
'0'
,
inj_ctrl_pic_ena_i
=>
'0'
);
);
-- Output registers (WB slave -> user design)
-- Output registers (WB slave -> user design)
...
@@ -112,6 +120,14 @@ package ep_wbgen2_pkg is
...
@@ -112,6 +120,14 @@ package ep_wbgen2_pkg is
dmcr_n_avg_load_o
:
std_logic
;
dmcr_n_avg_load_o
:
std_logic
;
dmsr_ps_rdy_o
:
std_logic
;
dmsr_ps_rdy_o
:
std_logic
;
dmsr_ps_rdy_load_o
:
std_logic
;
dmsr_ps_rdy_load_o
:
std_logic
;
inj_ctrl_pic_conf_ifg_o
:
std_logic_vector
(
15
downto
0
);
inj_ctrl_pic_conf_ifg_load_o
:
std_logic
;
inj_ctrl_pic_conf_sel_o
:
std_logic_vector
(
2
downto
0
);
inj_ctrl_pic_conf_sel_load_o
:
std_logic
;
inj_ctrl_pic_valid_o
:
std_logic
;
inj_ctrl_pic_valid_load_o
:
std_logic
;
inj_ctrl_pic_ena_o
:
std_logic
;
inj_ctrl_pic_ena_load_o
:
std_logic
;
end
record
;
end
record
;
constant
c_ep_out_registers_init_value
:
t_ep_out_registers
:
=
(
constant
c_ep_out_registers_init_value
:
t_ep_out_registers
:
=
(
...
@@ -168,7 +184,15 @@ package ep_wbgen2_pkg is
...
@@ -168,7 +184,15 @@ package ep_wbgen2_pkg is
dmcr_n_avg_o
=>
(
others
=>
'0'
),
dmcr_n_avg_o
=>
(
others
=>
'0'
),
dmcr_n_avg_load_o
=>
'0'
,
dmcr_n_avg_load_o
=>
'0'
,
dmsr_ps_rdy_o
=>
'0'
,
dmsr_ps_rdy_o
=>
'0'
,
dmsr_ps_rdy_load_o
=>
'0'
dmsr_ps_rdy_load_o
=>
'0'
,
inj_ctrl_pic_conf_ifg_o
=>
(
others
=>
'0'
),
inj_ctrl_pic_conf_ifg_load_o
=>
'0'
,
inj_ctrl_pic_conf_sel_o
=>
(
others
=>
'0'
),
inj_ctrl_pic_conf_sel_load_o
=>
'0'
,
inj_ctrl_pic_valid_o
=>
'0'
,
inj_ctrl_pic_valid_load_o
=>
'0'
,
inj_ctrl_pic_ena_o
=>
'0'
,
inj_ctrl_pic_ena_load_o
=>
'0'
);
);
function
"or"
(
left
,
right
:
t_ep_in_registers
)
return
t_ep_in_registers
;
function
"or"
(
left
,
right
:
t_ep_in_registers
)
return
t_ep_in_registers
;
function
f_x_to_zero
(
x
:
std_logic
)
return
std_logic
;
function
f_x_to_zero
(
x
:
std_logic
)
return
std_logic
;
...
@@ -214,6 +238,10 @@ tmp.dmcr_en_i := f_x_to_zero(left.dmcr_en_i) or f_x_to_zero(right.dmcr_en_i);
...
@@ -214,6 +238,10 @@ tmp.dmcr_en_i := f_x_to_zero(left.dmcr_en_i) or f_x_to_zero(right.dmcr_en_i);
tmp
.
dmcr_n_avg_i
:
=
f_x_to_zero
(
left
.
dmcr_n_avg_i
)
or
f_x_to_zero
(
right
.
dmcr_n_avg_i
);
tmp
.
dmcr_n_avg_i
:
=
f_x_to_zero
(
left
.
dmcr_n_avg_i
)
or
f_x_to_zero
(
right
.
dmcr_n_avg_i
);
tmp
.
dmsr_ps_val_i
:
=
f_x_to_zero
(
left
.
dmsr_ps_val_i
)
or
f_x_to_zero
(
right
.
dmsr_ps_val_i
);
tmp
.
dmsr_ps_val_i
:
=
f_x_to_zero
(
left
.
dmsr_ps_val_i
)
or
f_x_to_zero
(
right
.
dmsr_ps_val_i
);
tmp
.
dmsr_ps_rdy_i
:
=
f_x_to_zero
(
left
.
dmsr_ps_rdy_i
)
or
f_x_to_zero
(
right
.
dmsr_ps_rdy_i
);
tmp
.
dmsr_ps_rdy_i
:
=
f_x_to_zero
(
left
.
dmsr_ps_rdy_i
)
or
f_x_to_zero
(
right
.
dmsr_ps_rdy_i
);
tmp
.
inj_ctrl_pic_conf_ifg_i
:
=
f_x_to_zero
(
left
.
inj_ctrl_pic_conf_ifg_i
)
or
f_x_to_zero
(
right
.
inj_ctrl_pic_conf_ifg_i
);
tmp
.
inj_ctrl_pic_conf_sel_i
:
=
f_x_to_zero
(
left
.
inj_ctrl_pic_conf_sel_i
)
or
f_x_to_zero
(
right
.
inj_ctrl_pic_conf_sel_i
);
tmp
.
inj_ctrl_pic_valid_i
:
=
f_x_to_zero
(
left
.
inj_ctrl_pic_valid_i
)
or
f_x_to_zero
(
right
.
inj_ctrl_pic_valid_i
);
tmp
.
inj_ctrl_pic_ena_i
:
=
f_x_to_zero
(
left
.
inj_ctrl_pic_ena_i
)
or
f_x_to_zero
(
right
.
inj_ctrl_pic_ena_i
);
return
tmp
;
return
tmp
;
end
function
;
end
function
;
end
package
body
;
end
package
body
;
modules/wr_endpoint/ep_tx_inject_ctrl.vhd
0 → 100644
View file @
558b636f
-------------------------------------------------------------------------------
-- Title : Controller of
-- Project : White Rabbit MAC/Endpoint
-------------------------------------------------------------------------------
-- File : ep_tx_inject_ctrl.vhd
-- Author : Maciej Lipinski
-- Company : CERN BE-CO-HT
-- Created : 2014-01-16
-- Last update: 2014-01-16
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: this module enables to control HW packet injection in order
-- to turn the Endpoint into simple traffic generator for testing purposes
-------------------------------------------------------------------------------
--
-- Copyright (c) 2014 CERN / BE-CO-HT
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl-2.1.html
--
-------------------------------------------------------------------------------
library
ieee
;
use
ieee
.
std_logic_1164
.
all
;
use
ieee
.
numeric_std
.
all
;
library
work
;
use
work
.
wr_fabric_pkg
.
all
;
use
work
.
endpoint_private_pkg
.
all
;
use
work
.
ep_wbgen2_pkg
.
all
;
entity
ep_tx_inject_ctrl
is
generic
(
g_min_if_gap_length
:
integer
);
port
(
clk_sys_i
:
in
std_logic
;
rst_n_i
:
in
std_logic
;
snk_fab_i
:
in
t_ep_internal_fabric
;
snk_dreq_o
:
out
std_logic
;
src_fab_o
:
out
t_ep_internal_fabric
;
src_dreq_i
:
in
std_logic
;
inject_req_o
:
out
std_logic
;
inject_ready_i
:
in
std_logic
;
inject_packet_sel_o
:
out
std_logic_vector
(
2
downto
0
);
inject_user_value_o
:
out
std_logic_vector
(
15
downto
0
);
inject_ctr_ena_o
:
out
std_logic
;
regs_i
:
in
t_ep_out_registers
);
end
ep_tx_inject_ctrl
;
architecture
rtl
of
ep_tx_inject_ctrl
is
-- there a lag between setting inject_req and SOF, this nees to be included
constant
if_gap_offset
:
unsigned
(
15
downto
0
)
:
=
x"0000"
;
-- unused
constant
src_fab_null
:
t_ep_internal_fabric
:
=
(
sof
=>
'0'
,
eof
=>
'0'
,
error
=>
'0'
,
dvalid
=>
'0'
,
bytesel
=>
'0'
,
has_rx_timestamp
=>
'0'
,
rx_timestamp_valid
=>
'0'
,
data
=>
(
others
=>
'0'
),
addr
=>
(
others
=>
'0'
));
type
t_state
is
(
IDLE
,
INJECT_REQ
,
INJECT
,
IFG
);
-- Wishbone settings
signal
if_gap_value
:
unsigned
(
15
downto
0
);
signal
pck_sel
:
std_logic_vector
(
2
downto
0
);
signal
gen_ena
:
std_logic
;
signal
if_gap_cnt
:
unsigned
(
15
downto
0
);
signal
frame_id_cnt
:
unsigned
(
15
downto
0
);
signal
within_packet
:
std_logic
;
signal
state
:
t_state
;
begin
-- rtl
p_detect_within
:
process
(
clk_sys_i
)
begin
if
rising_edge
(
clk_sys_i
)
then
if
rst_n_i
=
'0'
then
within_packet
<=
'0'
;
else
if
(
snk_fab_i
.
sof
=
'1'
)
then
within_packet
<=
'1'
;
end
if
;
if
(
snk_fab_i
.
eof
=
'1'
or
snk_fab_i
.
error
=
'1'
)
then
within_packet
<=
'0'
;
end
if
;
end
if
;
end
if
;
end
process
;
p_config_reg
:
process
(
clk_sys_i
)
begin
if
rising_edge
(
clk_sys_i
)
then
if
rst_n_i
=
'0'
then
if_gap_value
<=
(
others
=>
'0'
);
pck_sel
<=
(
others
=>
'0'
);
gen_ena
<=
'0'
;
else
if
(
regs_i
.
inj_ctrl_pic_ena_load_o
=
'1'
)
then
-- writing the register
if
(
regs_i
.
inj_ctrl_pic_valid_o
=
'1'
)
then
if_gap_value
<=
unsigned
(
regs_i
.
inj_ctrl_pic_conf_ifg_o
);
pck_sel
<=
regs_i
.
inj_ctrl_pic_conf_sel_o
;
end
if
;
gen_ena
<=
regs_i
.
inj_ctrl_pic_ena_o
;
end
if
;
end
if
;
end
if
;
end
process
;
p_ctrl_fsm
:
process
(
clk_sys_i
)
begin
if
rising_edge
(
clk_sys_i
)
then
if
rst_n_i
=
'0'
then
state
<=
IDLE
;
inject_req_o
<=
'0'
;
if_gap_cnt
<=
(
others
=>
'0'
);
frame_id_cnt
<=
(
others
=>
'0'
);
else
case
state
is
when
IDLE
=>
if
(
gen_ena
=
'1'
and
within_packet
=
'0'
)
then
inject_req_o
<=
'1'
;
if_gap_cnt
<=
if_gap_offset
;
frame_id_cnt
<=
(
others
=>
'0'
);
state
<=
INJECT_REQ
;
end
if
;
when
INJECT_REQ
=>
inject_req_o
<=
'0'
;
state
<=
INJECT
;
when
INJECT
=>
if
(
inject_ready_i
=
'1'
)
then
frame_id_cnt
<=
frame_id_cnt
+
1
;
state
<=
IFG
;
end
if
;
when
IFG
=>
if
(
gen_ena
=
'0'
or
within_packet
=
'1'
)
then
--gen disabled or "impossible excep"
state
<=
IDLE
;
if_gap_cnt
<=
(
others
=>
'0'
);
frame_id_cnt
<=
(
others
=>
'0'
);
elsif
(
if_gap_cnt
<
if_gap_value
)
then
if_gap_cnt
<=
if_gap_cnt
+
1
;
else
inject_req_o
<=
'1'
;
if_gap_cnt
<=
if_gap_offset
;
state
<=
INJECT_REQ
;
end
if
;
when
others
=>
state
<=
IDLE
;
if_gap_cnt
<=
(
others
=>
'0'
);
frame_id_cnt
<=
(
others
=>
'0'
);
end
case
;
end
if
;
end
if
;
end
process
;
inject_user_value_o
<=
std_logic_vector
(
frame_id_cnt
);
inject_packet_sel_o
<=
pck_sel
;
inject_ctr_ena_o
<=
gen_ena
;
snk_dreq_o
<=
src_dreq_i
when
(
state
=
IDLE
)
else
'1'
;
-- dev/null if gen
src_fab_o
<=
snk_fab_i
when
(
state
=
IDLE
)
else
src_fab_null
;
-- dev/null if gen
end
rtl
;
modules/wr_endpoint/ep_tx_packet_injection.vhd
View file @
558b636f
...
@@ -144,17 +144,23 @@ begin -- rtl
...
@@ -144,17 +144,23 @@ begin -- rtl
begin
begin
if
rising_edge
(
clk_sys_i
)
then
if
rising_edge
(
clk_sys_i
)
then
if
rst_n_i
=
'0'
then
if
rst_n_i
=
'0'
then
state
<=
WAIT_IDLE
;
state
<=
WAIT_IDLE
;
select_inject
<=
'0'
;
select_inject
<=
'0'
;
no_template_error
<=
'0'
;
no_template_error
<=
'0'
;
inj_src
.
sof
<=
'0'
;
inj_src
.
eof
<=
'0'
;
inj_src
.
dvalid
<=
'0'
;
inj_src
.
bytesel
<=
'0'
;
first_word
<=
'0'
;
else
else
case
state
is
case
state
is
when
WAIT_IDLE
=>
when
WAIT_IDLE
=>
inj_src
.
sof
<=
'0'
;
inj_src
.
sof
<=
'0'
;
inj_src
.
eof
<=
'0'
;
inj_src
.
eof
<=
'0'
;
inj_src
.
dvalid
<=
'0'
;
inj_src
.
dvalid
<=
'0'
;
inj_src
.
bytesel
<=
'0'
;
no_template_error
<=
'0'
;
no_template_error
<=
'0'
;
first_word
<=
'0'
;
first_word
<=
'0'
;
if
(
inject_req_i
=
'1'
)
then
--ML: we make sure that we remember the packet_sel_i
if
(
inject_req_i
=
'1'
)
then
--ML: we make sure that we remember the packet_sel_i
-- only when req_i HIGH
-- only when req_i HIGH
...
@@ -197,11 +203,13 @@ begin -- rtl
...
@@ -197,11 +203,13 @@ begin -- rtl
end
if
;
end
if
;
if
(
template_last
=
'1'
and
inj_src
.
dvalid
=
'1'
and
first_word
=
'0'
)
then
if
(
template_last
=
'1'
and
inj_src
.
dvalid
=
'1'
and
first_word
=
'0'
)
then
inj_src
.
bytesel
<=
template_user
;
state
<=
EOF
;
state
<=
EOF
;
end
if
;
end
if
;
when
EOF
=>
when
EOF
=>
inj_src
.
dvalid
<=
'0'
;
inj_src
.
dvalid
<=
'0'
;
inj_src
.
bytesel
<=
'0'
;
if
(
src_dreq_i
=
'1'
)
then
if
(
src_dreq_i
=
'1'
)
then
inj_src
.
eof
<=
'1'
;
inj_src
.
eof
<=
'1'
;
state
<=
WAIT_IDLE
;
state
<=
WAIT_IDLE
;
...
@@ -212,12 +220,12 @@ begin -- rtl
...
@@ -212,12 +220,12 @@ begin -- rtl
end
if
;
end
if
;
end
process
;
end
process
;
inj_src
.
bytesel
<=
'0'
;
--
inj_src.bytesel <= '0';
inj_src
.
error
<=
'0'
;
inj_src
.
error
<=
'0'
;
p_inj_src_data
:
process
(
template_user
,
inject_user_value_i
,
mem_data_i
)
p_inj_src_data
:
process
(
template_user
,
inject_user_value_i
,
mem_data_i
,
template_last
,
first_word
)
begin
begin
if
(
template_user
=
'1'
)
then
if
(
template_user
=
'1'
and
template_last
=
'0'
and
first_word
=
'0'
)
then
inj_src
.
data
<=
inject_user_value_i
;
inj_src
.
data
<=
inject_user_value_i
;
else
else
inj_src
.
data
<=
mem_data_i
(
15
downto
0
);
inj_src
.
data
<=
mem_data_i
(
15
downto
0
);
...
...
modules/wr_endpoint/ep_tx_path.vhd
View file @
558b636f
...
@@ -50,6 +50,7 @@ entity ep_tx_path is
...
@@ -50,6 +50,7 @@ entity ep_tx_path is
g_with_vlans
:
boolean
;
g_with_vlans
:
boolean
;
g_with_timestamper
:
boolean
;
g_with_timestamper
:
boolean
;
g_with_packet_injection
:
boolean
;
g_with_packet_injection
:
boolean
;
g_with_inj_ctrl
:
boolean
:
=
true
;
g_force_gap_length
:
integer
g_force_gap_length
:
integer
);
);
...
@@ -143,14 +144,26 @@ architecture rtl of ep_tx_path is
...
@@ -143,14 +144,26 @@ architecture rtl of ep_tx_path is
type
t_fab_pipe
is
array
(
integer
range
<>
)
of
t_ep_internal_fabric
;
type
t_fab_pipe
is
array
(
integer
range
<>
)
of
t_ep_internal_fabric
;
signal
fab_pipe
:
t_fab_pipe
(
3
downto
0
);
signal
fab_pipe
:
t_fab_pipe
(
4
downto
0
);
signal
dreq_pipe
:
std_logic_vector
(
3
downto
0
);
signal
dreq_pipe
:
std_logic_vector
(
4
downto
0
);
signal
vlan_mem_addr
:
std_logic_vector
(
9
downto
0
);
signal
vlan_mem_addr
:
std_logic_vector
(
9
downto
0
);
signal
vlan_mem_data
:
std_logic_vector
(
17
downto
0
);
signal
vlan_mem_data
:
std_logic_vector
(
17
downto
0
);
signal
txtsu_stb
:
std_logic
;
signal
txtsu_stb
:
std_logic
;
signal
inject_req
:
std_logic
;
signal
inject_ready
:
std_logic
;
signal
inject_packet_sel
:
std_logic_vector
(
2
downto
0
);
signal
inject_user_value
:
std_logic_vector
(
15
downto
0
);
signal
inj_ctr_req
:
std_logic
;
signal
inj_ctr_ready
:
std_logic
;
signal
inj_ctr_packet_sel
:
std_logic_vector
(
2
downto
0
);
signal
inj_ctr_user_value
:
std_logic_vector
(
15
downto
0
);
signal
inj_ctr_ena
:
std_logic
;
begin
-- rtl
begin
-- rtl
U_Header_Processor
:
ep_tx_header_processor
U_Header_Processor
:
ep_tx_header_processor
...
@@ -207,55 +220,100 @@ begin -- rtl
...
@@ -207,55 +220,100 @@ begin -- rtl
end
generate
gen_without_vlan_unit
;
end
generate
gen_without_vlan_unit
;
gen_with_injection
:
if
(
g_with_packet_injection
)
generate
gen_with_injection
:
if
(
g_with_packet_injection
)
generate
gen_with_inj_ctrl
:
if
(
g_with_inj_ctrl
)
generate
U_Injector_ctr
:
ep_tx_inject_ctrl
generic
map
(
g_min_if_gap_length
=>
5
)
port
map
(
clk_sys_i
=>
clk_sys_i
,
rst_n_i
=>
rst_n_i
,
snk_fab_i
=>
fab_pipe
(
1
),
snk_dreq_o
=>
dreq_pipe
(
1
),
src_fab_o
=>
fab_pipe
(
2
),
src_dreq_i
=>
dreq_pipe
(
2
),
inject_req_o
=>
inj_ctr_req
,
inject_ready_i
=>
inj_ctr_ready
,
inject_packet_sel_o
=>
inj_ctr_packet_sel
,
inject_user_value_o
=>
inj_ctr_user_value
,
inject_ctr_ena_o
=>
inj_ctr_ena
,
regs_i
=>
regs_i
);
end
generate
gen_with_inj_ctrl
;
U_Injector
:
ep_tx_packet_injection
U_Injector
:
ep_tx_packet_injection
port
map
(
port
map
(
clk_sys_i
=>
clk_sys_i
,
clk_sys_i
=>
clk_sys_i
,
rst_n_i
=>
rst_n_i
,
rst_n_i
=>
rst_n_i
,
snk_fab_i
=>
fab_pipe
(
1
),
snk_fab_i
=>
fab_pipe
(
2
),
snk_dreq_o
=>
dreq_pipe
(
1
),
snk_dreq_o
=>
dreq_pipe
(
2
),
src_fab_o
=>
fab_pipe
(
2
),
src_fab_o
=>
fab_pipe
(
3
),
src_dreq_i
=>
dreq_pipe
(
2
),
src_dreq_i
=>
dreq_pipe
(
3
),
inject_req_i
=>
inject_req
_i
,
inject_req_i
=>
inject_req
,
inject_ready_o
=>
inject_ready
_o
,
inject_ready_o
=>
inject_ready
,
inject_packet_sel_i
=>
inject_packet_sel
_i
,
inject_packet_sel_i
=>
inject_packet_sel
,
inject_user_value_i
=>
inject_user_value
_i
,
inject_user_value_i
=>
inject_user_value
,
mem_addr_o
=>
vlan_mem_addr
,
mem_addr_o
=>
vlan_mem_addr
,
mem_data_i
=>
vlan_mem_data
);
mem_data_i
=>
vlan_mem_data
);
end
generate
gen_with_injection
;
end
generate
gen_with_injection
;
inject_req
<=
inj_ctr_req
when
(
inj_ctr_ena
=
'1'
)
else
inject_req_i
;
inject_packet_sel
<=
inj_ctr_packet_sel
when
(
inj_ctr_ena
=
'1'
)
else
inject_packet_sel_i
;
inject_user_value
<=
inj_ctr_user_value
when
(
inj_ctr_ena
=
'1'
)
else
inject_user_value_i
;
inj_ctr_ready
<=
inject_ready
;
inject_ready_o
<=
inject_ready
;
gen_without_inj_ctrl
:
if
(
not
g_with_inj_ctrl
or
not
g_with_packet_injection
)
generate
fab_pipe
(
2
)
<=
fab_pipe
(
1
);
dreq_pipe
(
1
)
<=
dreq_pipe
(
2
);
inj_ctr_req
<=
'0'
;
inj_ctr_ready
<=
'0'
;
inj_ctr_packet_sel
<=
(
others
=>
'0'
);
inj_ctr_user_value
<=
(
others
=>
'0'
);
inj_ctr_ena
<=
'0'
;
end
generate
gen_without_inj_ctrl
;
gen_without_injection
:
if
(
not
g_with_packet_injection
)
generate
gen_without_injection
:
if
(
not
g_with_packet_injection
)
generate
fab_pipe
(
2
)
<=
fab_pipe
(
1
);
fab_pipe
(
3
)
<=
fab_pipe
(
2
);
dreq_pipe
(
1
)
<=
dreq_pipe
(
2
);
dreq_pipe
(
2
)
<=
dreq_pipe
(
3
);
end
generate
gen_without_injection
;
end
generate
gen_without_injection
;
U_Insert_CRC
:
ep_tx_crc_inserter
U_Insert_CRC
:
ep_tx_crc_inserter
port
map
(
port
map
(
clk_sys_i
=>
clk_sys_i
,
clk_sys_i
=>
clk_sys_i
,
rst_n_i
=>
rst_n_i
,
rst_n_i
=>
rst_n_i
,
snk_fab_i
=>
fab_pipe
(
2
),
snk_fab_i
=>
fab_pipe
(
3
),
snk_dreq_o
=>
dreq_pipe
(
2
),
snk_dreq_o
=>
dreq_pipe
(
3
),
src_fab_o
=>
fab_pipe
(
3
),
src_fab_o
=>
fab_pipe
(
4
),
src_dreq_i
=>
dreq_pipe
(
3
),
src_dreq_i
=>
dreq_pipe
(
4
),
dbg_o
=>
dbg_o
(
33
downto
31
));
dbg_o
=>
dbg_o
(
33
downto
31
));
pcs_fab_o
<=
fab_pipe
(
3
);
pcs_fab_o
<=
fab_pipe
(
4
);
dreq_pipe
(
3
)
<=
pcs_dreq_i
;
dreq_pipe
(
4
)
<=
pcs_dreq_i
;
-- GEN_DBG: for i in 0 to 3 generate
-- dbg_o(i) <= fab_pipe(i).sof;
-- dbg_o(i+4) <= fab_pipe(i).eof;
-- end generate GEN_DBG;
dbg_o
(
0
)
<=
fab_pipe
(
0
)
.
sof
;
dbg_o
(
1
)
<=
fab_pipe
(
2
)
.
sof
;
dbg_o
(
2
)
<=
fab_pipe
(
3
)
.
sof
;
dbg_o
(
3
)
<=
fab_pipe
(
4
)
.
sof
;
dbg_o
(
4
)
<=
fab_pipe
(
0
)
.
eof
;
dbg_o
(
5
)
<=
fab_pipe
(
2
)
.
eof
;
dbg_o
(
6
)
<=
fab_pipe
(
3
)
.
eof
;
dbg_o
(
7
)
<=
fab_pipe
(
4
)
.
eof
;
GEN_DBG
:
for
i
in
0
to
3
generate
dbg_o
(
i
)
<=
fab_pipe
(
i
)
.
sof
;
dbg_o
(
i
+
4
)
<=
fab_pipe
(
i
)
.
eof
;
end
generate
GEN_DBG
;
dbg_o
(
8
)
<=
dreq_pipe
(
0
);
dbg_o
(
8
)
<=
dreq_pipe
(
0
);
dbg_o
(
9
)
<=
dreq_pipe
(
1
);
dbg_o
(
9
)
<=
dreq_pipe
(
2
);
dbg_o
(
10
)
<=
dreq_pipe
(
2
);
dbg_o
(
10
)
<=
dreq_pipe
(
3
);
dbg_o
(
11
)
<=
fab_pipe
(
0
)
.
dvalid
;
dbg_o
(
11
)
<=
fab_pipe
(
0
)
.
dvalid
;
dbg_o
(
12
)
<=
fab_pipe
(
3
)
.
dvalid
;
dbg_o
(
12
)
<=
fab_pipe
(
4
)
.
dvalid
;
-- new 4 bits
-- new 4 bits
dbg_o
(
13
)
<=
dreq_pipe
(
3
);
dbg_o
(
13
)
<=
dreq_pipe
(
4
);
dbg_o
(
14
)
<=
txtsu_stb
;
dbg_o
(
14
)
<=
txtsu_stb
;
dbg_o
(
15
)
<=
txtsu_ack_i
;
dbg_o
(
15
)
<=
txtsu_ack_i
;
dbg_o
(
16
)
<=
fab_pipe
(
1
)
.
dvalid
;
dbg_o
(
16
)
<=
fab_pipe
(
2
)
.
dvalid
;
-- dbg_o(28 downto 13) <= fab_pipe(2).data;
-- dbg_o(28 downto 13) <= fab_pipe(2).data;
dbg_o
(
28
downto
17
)
<=
fab_pipe
(
2
)
.
data
(
11
downto
0
);
dbg_o
(
28
downto
17
)
<=
fab_pipe
(
3
)
.
data
(
11
downto
0
);
dbg_o
(
30
downto
29
)
<=
fab_pipe
(
2
)
.
addr
;
dbg_o
(
30
downto
29
)
<=
fab_pipe
(
3
)
.
addr
;
end
rtl
;
end
rtl
;
modules/wr_endpoint/ep_wishbone_controller.vhd
View file @
558b636f
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
---------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------
-- File : ep_wishbone_controller.vhd
-- File : ep_wishbone_controller.vhd
-- Author : auto-generated by wbgen2 from ep_wishbone_controller.wb
-- Author : auto-generated by wbgen2 from ep_wishbone_controller.wb
-- Created : T
ue Mar 12 16:46:42 2013
-- Created : T
hu Jan 16 14:57:37 2014
-- Standard : VHDL'87
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE ep_wishbone_controller.wb
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE ep_wishbone_controller.wb
...
@@ -151,6 +151,10 @@ begin
...
@@ -151,6 +151,10 @@ begin
regs_o
.
dmcr_en_load_o
<=
'0'
;
regs_o
.
dmcr_en_load_o
<=
'0'
;
regs_o
.
dmcr_n_avg_load_o
<=
'0'
;
regs_o
.
dmcr_n_avg_load_o
<=
'0'
;
regs_o
.
dmsr_ps_rdy_load_o
<=
'0'
;
regs_o
.
dmsr_ps_rdy_load_o
<=
'0'
;
regs_o
.
inj_ctrl_pic_conf_ifg_load_o
<=
'0'
;
regs_o
.
inj_ctrl_pic_conf_sel_load_o
<=
'0'
;
regs_o
.
inj_ctrl_pic_valid_load_o
<=
'0'
;
regs_o
.
inj_ctrl_pic_ena_load_o
<=
'0'
;
elsif
rising_edge
(
clk_sys_i
)
then
elsif
rising_edge
(
clk_sys_i
)
then
-- advance the ACK generator shift register
-- advance the ACK generator shift register
ack_sreg
(
8
downto
0
)
<=
ack_sreg
(
9
downto
1
);
ack_sreg
(
8
downto
0
)
<=
ack_sreg
(
9
downto
1
);
...
@@ -170,6 +174,10 @@ begin
...
@@ -170,6 +174,10 @@ begin
regs_o
.
dmcr_en_load_o
<=
'0'
;
regs_o
.
dmcr_en_load_o
<=
'0'
;
regs_o
.
dmcr_n_avg_load_o
<=
'0'
;
regs_o
.
dmcr_n_avg_load_o
<=
'0'
;
regs_o
.
dmsr_ps_rdy_load_o
<=
'0'
;
regs_o
.
dmsr_ps_rdy_load_o
<=
'0'
;
regs_o
.
inj_ctrl_pic_conf_ifg_load_o
<=
'0'
;
regs_o
.
inj_ctrl_pic_conf_sel_load_o
<=
'0'
;
regs_o
.
inj_ctrl_pic_valid_load_o
<=
'0'
;
regs_o
.
inj_ctrl_pic_ena_load_o
<=
'0'
;
ack_in_progress
<=
'0'
;
ack_in_progress
<=
'0'
;
else
else
ep_tscr_cs_start_int
<=
ep_tscr_cs_start_int_delay
;
ep_tscr_cs_start_int
<=
ep_tscr_cs_start_int_delay
;
...
@@ -188,6 +196,10 @@ begin
...
@@ -188,6 +196,10 @@ begin
regs_o
.
dmcr_en_load_o
<=
'0'
;
regs_o
.
dmcr_en_load_o
<=
'0'
;
regs_o
.
dmcr_n_avg_load_o
<=
'0'
;
regs_o
.
dmcr_n_avg_load_o
<=
'0'
;
regs_o
.
dmsr_ps_rdy_load_o
<=
'0'
;
regs_o
.
dmsr_ps_rdy_load_o
<=
'0'
;
regs_o
.
inj_ctrl_pic_conf_ifg_load_o
<=
'0'
;
regs_o
.
inj_ctrl_pic_conf_sel_load_o
<=
'0'
;
regs_o
.
inj_ctrl_pic_valid_load_o
<=
'0'
;
regs_o
.
inj_ctrl_pic_ena_load_o
<=
'0'
;
end
if
;
end
if
;
else
else
if
((
wb_cyc_i
=
'1'
)
and
(
wb_stb_i
=
'1'
))
then
if
((
wb_cyc_i
=
'1'
)
and
(
wb_stb_i
=
'1'
))
then
...
@@ -200,7 +212,7 @@ begin
...
@@ -200,7 +212,7 @@ begin
ep_ecr_rx_en_int
<=
wrdata_reg
(
7
);
ep_ecr_rx_en_int
<=
wrdata_reg
(
7
);
end
if
;
end
if
;
rddata_reg
(
4
downto
0
)
<=
ep_ecr_portid_int
;
rddata_reg
(
4
downto
0
)
<=
ep_ecr_portid_int
;
rddata_reg
(
5
)
<=
'
0
'
;
rddata_reg
(
5
)
<=
'
X
'
;
rddata_reg
(
6
)
<=
ep_ecr_tx_en_int
;
rddata_reg
(
6
)
<=
ep_ecr_tx_en_int
;
rddata_reg
(
7
)
<=
ep_ecr_rx_en_int
;
rddata_reg
(
7
)
<=
ep_ecr_rx_en_int
;
rddata_reg
(
24
)
<=
regs_i
.
ecr_feat_vlan_i
;
rddata_reg
(
24
)
<=
regs_i
.
ecr_feat_vlan_i
;
...
@@ -240,9 +252,9 @@ begin
...
@@ -240,9 +252,9 @@ begin
end
if
;
end
if
;
rddata_reg
(
0
)
<=
ep_tscr_en_txts_int
;
rddata_reg
(
0
)
<=
ep_tscr_en_txts_int
;
rddata_reg
(
1
)
<=
ep_tscr_en_rxts_int
;
rddata_reg
(
1
)
<=
ep_tscr_en_rxts_int
;
rddata_reg
(
2
)
<=
'
0
'
;
rddata_reg
(
2
)
<=
'
X
'
;
rddata_reg
(
3
)
<=
ep_tscr_cs_done_sync1
;
rddata_reg
(
3
)
<=
ep_tscr_cs_done_sync1
;
rddata_reg
(
4
)
<=
'
0
'
;
rddata_reg
(
4
)
<=
'
X
'
;
rddata_reg
(
5
)
<=
regs_i
.
tscr_rx_cal_result_i
;
rddata_reg
(
5
)
<=
regs_i
.
tscr_rx_cal_result_i
;
rddata_reg
(
6
)
<=
'X'
;
rddata_reg
(
6
)
<=
'X'
;
rddata_reg
(
7
)
<=
'X'
;
rddata_reg
(
7
)
<=
'X'
;
...
@@ -642,6 +654,30 @@ begin
...
@@ -642,6 +654,30 @@ begin
rddata_reg
(
31
)
<=
'X'
;
rddata_reg
(
31
)
<=
'X'
;
ack_sreg
(
0
)
<=
'1'
;
ack_sreg
(
0
)
<=
'1'
;
ack_in_progress
<=
'1'
;
ack_in_progress
<=
'1'
;
when
"10001"
=>
if
(
wb_we_i
=
'1'
)
then
regs_o
.
inj_ctrl_pic_conf_ifg_load_o
<=
'1'
;
regs_o
.
inj_ctrl_pic_conf_sel_load_o
<=
'1'
;
regs_o
.
inj_ctrl_pic_valid_load_o
<=
'1'
;
regs_o
.
inj_ctrl_pic_ena_load_o
<=
'1'
;
end
if
;
rddata_reg
(
15
downto
0
)
<=
regs_i
.
inj_ctrl_pic_conf_ifg_i
;
rddata_reg
(
18
downto
16
)
<=
regs_i
.
inj_ctrl_pic_conf_sel_i
;
rddata_reg
(
20
)
<=
regs_i
.
inj_ctrl_pic_valid_i
;
rddata_reg
(
21
)
<=
regs_i
.
inj_ctrl_pic_ena_i
;
rddata_reg
(
19
)
<=
'X'
;
rddata_reg
(
22
)
<=
'X'
;
rddata_reg
(
23
)
<=
'X'
;
rddata_reg
(
24
)
<=
'X'
;
rddata_reg
(
25
)
<=
'X'
;
rddata_reg
(
26
)
<=
'X'
;
rddata_reg
(
27
)
<=
'X'
;
rddata_reg
(
28
)
<=
'X'
;
rddata_reg
(
29
)
<=
'X'
;
rddata_reg
(
30
)
<=
'X'
;
rddata_reg
(
31
)
<=
'X'
;
ack_sreg
(
0
)
<=
'1'
;
ack_in_progress
<=
'1'
;
when
others
=>
when
others
=>
-- prevent the slave from hanging the bus on invalid address
-- prevent the slave from hanging the bus on invalid address
ack_in_progress
<=
'1'
;
ack_in_progress
<=
'1'
;
...
@@ -810,6 +846,14 @@ begin
...
@@ -810,6 +846,14 @@ begin
-- DMTD Phase shift value
-- DMTD Phase shift value
-- DMTD Phase shift value ready
-- DMTD Phase shift value ready
regs_o
.
dmsr_ps_rdy_o
<=
wrdata_reg
(
24
);
regs_o
.
dmsr_ps_rdy_o
<=
wrdata_reg
(
24
);
-- Config: Interframe GAP
regs_o
.
inj_ctrl_pic_conf_ifg_o
<=
wrdata_reg
(
15
downto
0
);
-- Config: packet pattern sel id
regs_o
.
inj_ctrl_pic_conf_sel_o
<=
wrdata_reg
(
18
downto
16
);
-- Interframe GAP config valid
regs_o
.
inj_ctrl_pic_valid_o
<=
wrdata_reg
(
20
);
-- Frame Generation Enabled
regs_o
.
inj_ctrl_pic_ena_o
<=
wrdata_reg
(
21
);
rwaddr_reg
<=
wb_adr_i
;
rwaddr_reg
<=
wb_adr_i
;
wb_stall_o
<=
(
not
ack_sreg
(
0
))
and
(
wb_stb_i
and
wb_cyc_i
);
wb_stall_o
<=
(
not
ack_sreg
(
0
))
and
(
wb_stb_i
and
wb_cyc_i
);
-- ACK signal generation. Just pass the LSB of ACK counter.
-- ACK signal generation. Just pass the LSB of ACK counter.
...
...
modules/wr_endpoint/ep_wishbone_controller.wb
View file @
558b636f
...
@@ -665,5 +665,49 @@ peripheral {
...
@@ -665,5 +665,49 @@ peripheral {
access_bus = READ_WRITE;
access_bus = READ_WRITE;
};
};
};
};
reg {
name = "PCK Injection CTRL";
prefix = "INJ_CTRL";
field {
name = "Config: Interframe GAP";
prefix = "PIC_CONF_IFG";
size = 16;
type = SLV;
access_dev = READ_WRITE;
access_bus = READ_WRITE;
load = LOAD_EXT;
};
field {
name = "Config: packet pattern sel id";
prefix = "PIC_CONF_SEL";
size = 3;
type = SLV;
access_dev = READ_WRITE;
access_bus = READ_WRITE;
load = LOAD_EXT;
};
field {
name = "Interframe GAP config valid";
prefix = "PIC_VALID";
type = BIT;
align = 4;
access_dev = READ_WRITE;
access_bus = READ_WRITE;
load = LOAD_EXT;
};
field {
name = "Frame Generation Enabled";
prefix = "PIC_ENA";
type = BIT;
access_dev = READ_WRITE;
access_bus = READ_WRITE;
load = LOAD_EXT;
};
};
};
};
sim/endpoint_regs.v
View file @
558b636f
...
@@ -24,6 +24,10 @@
...
@@ -24,6 +24,10 @@
`define
EP_TSCR_CS_START 32
'
h00000004
`define
EP_TSCR_CS_START 32
'
h00000004
`define
EP_TSCR_CS_DONE_OFFSET 3
`define
EP_TSCR_CS_DONE_OFFSET 3
`define
EP_TSCR_CS_DONE 32
'
h00000008
`define
EP_TSCR_CS_DONE 32
'
h00000008
`define
EP_TSCR_RX_CAL_START_OFFSET 4
`define
EP_TSCR_RX_CAL_START 32
'
h00000010
`define
EP_TSCR_RX_CAL_RESULT_OFFSET 5
`define
EP_TSCR_RX_CAL_RESULT 32
'
h00000020
`define
ADDR_EP_RFCR 7
'
h8
`define
ADDR_EP_RFCR 7
'
h8
`define
EP_RFCR_A_RUNT_OFFSET 0
`define
EP_RFCR_A_RUNT_OFFSET 0
`define
EP_RFCR_A_RUNT 32
'
h00000001
`define
EP_RFCR_A_RUNT 32
'
h00000001
...
@@ -111,3 +115,12 @@
...
@@ -111,3 +115,12 @@
`define
EP_DMSR_PS_VAL 32
'
h00ffffff
`define
EP_DMSR_PS_VAL 32
'
h00ffffff
`define
EP_DMSR_PS_RDY_OFFSET 24
`define
EP_DMSR_PS_RDY_OFFSET 24
`define
EP_DMSR_PS_RDY 32
'
h01000000
`define
EP_DMSR_PS_RDY 32
'
h01000000
`define
ADDR_EP_INJ_CTRL 7
'
h44
`define
EP_INJ_CTRL_PIC_CONF_IFG_OFFSET 0
`define
EP_INJ_CTRL_PIC_CONF_IFG 32
'
h0000ffff
`define
EP_INJ_CTRL_PIC_CONF_SEL_OFFSET 16
`define
EP_INJ_CTRL_PIC_CONF_SEL 32
'
h00070000
`define
EP_INJ_CTRL_PIC_VALID_OFFSET 20
`define
EP_INJ_CTRL_PIC_VALID 32
'
h00100000
`define
EP_INJ_CTRL_PIC_ENA_OFFSET 21
`define
EP_INJ_CTRL_PIC_ENA 32
'
h00200000
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