Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
gtxe2_gpl
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Elphel
gtxe2_gpl
Commits
9aabc22e
Commit
9aabc22e
authored
Aug 25, 2015
by
Alexey Grebenkin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed bugs, found while x393_sata testing
parent
789d67eb
Changes
16
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
677 additions
and
113 deletions
+677
-113
GTXE2_CHANNEL.v
GTXE2_CHANNEL.v
+309
-47
GTXE2_CHANNEL_GPL.v
gtxe2_channel/GTXE2_CHANNEL_GPL.v
+23
-19
gtxe2_chnl.v
gtxe2_channel/gtxe2_chnl.v
+5
-8
gtxe2_chnl_clocking.v
gtxe2_channel/gtxe2_chnl_clocking.v
+6
-4
gtxe2_chnl_cpll.v
gtxe2_channel/gtxe2_chnl_cpll.v
+1
-1
gtxe2_chnl_rx.v
gtxe2_channel/gtxe2_chnl_rx.v
+41
-6
gtxe2_chnl_rx_align.v
gtxe2_channel/gtxe2_chnl_rx_align.v
+26
-1
gtxe2_chnl_rx_dataiface.v
gtxe2_channel/gtxe2_chnl_rx_dataiface.v
+108
-0
gtxe2_chnl_rx_des.v
gtxe2_channel/gtxe2_chnl_rx_des.v
+1
-1
gtxe2_chnl_rx_oob.v
gtxe2_channel/gtxe2_chnl_rx_oob.v
+22
-5
gtxe2_chnl_tx.v
gtxe2_channel/gtxe2_chnl_tx.v
+42
-8
gtxe2_chnl_tx_8x10enc.v
gtxe2_channel/gtxe2_chnl_tx_8x10enc.v
+4
-4
gtxe2_chnl_tx_dataiface.v
gtxe2_channel/gtxe2_chnl_tx_dataiface.v
+80
-0
gtxe2_chnl_tx_oob.v
gtxe2_channel/gtxe2_chnl_tx_oob.v
+6
-6
gtxe2_chnl_tx_ser.v
gtxe2_channel/gtxe2_chnl_tx_ser.v
+1
-1
tb.v
tb/tb.v
+2
-2
No files found.
GTXE2_CHANNEL.v
View file @
9aabc22e
/*******************************************************************************
* Module: GTXE2_CHANNEL
* Date: 2015-0
7-08
* Date: 2015-0
8-24
* Author: Alexey
* Description: emulates GTXE2_CHANNEL primitive behaviour.
* The file is gathered from multiple files
...
...
@@ -256,6 +256,7 @@ module gtxe2_chnl_clocking(
input
wire
[
2
:
0
]
TXOUTCLKSEL
,
input
wire
[
2
:
0
]
RXOUTCLKSEL
,
input
wire
TXDLYBYPASS
,
input
wire
RXDLYBYPASS
,
output
wire
GTREFCLKMONITOR
,
input
wire
CPLLLOCKDETCLK
,
...
...
@@ -363,6 +364,7 @@ tx_toserialclk_div(
.
div
(
tx_serial_divider
)
)
;
wire
rx_sipo_clk
;
clock_divider
#(
// .divide_by (rx_serial_divider),
.
divide_by_param
(
0
)
...
...
@@ -629,7 +631,7 @@ wire [word_count - 1:0] word_disparity;
wire
[
word_count
-
1
:
0
]
interm_disparity
;
wire
[
5
:
0
]
six
[
word_count
-
1
:
0
]
;
wire
[
3
:
0
]
four
[
word_count
-
1
:
0
]
;
wire
[
owidth
-
1
:
0
]
oword
[
word_count
-
1
:
0
]
;
wire
[
9
:
0
]
oword
[
word_count
-
1
:
0
]
;
wire
[
iwidth
-
1
:
0
]
iword
[
word_count
-
1
:
0
]
;
wire
[
word_count
-
1
:
0
]
is_control
;
...
...
@@ -644,7 +646,7 @@ begin: encode_by_word
assign
iword
[
ii
]
=
data_in
[
ii
*
8
+
7
:
ii
*
8
]
;
assign
interm_disparity
[
ii
]
=
^
six
[
ii
]
?
word_disparity
[
ii
]
:
~
word_disparity
[
ii
]
;
assign
word_disparity
[
ii
]
=
(
ii
==
0
)
?
disparity
:
(
^
oword
[
ii
-
1
]
?
~
word_disparity
[
ii
-
1
]
:
word_disparity
[
ii
-
1
])
;
(
^
oword
[
ii
-
1
]
?
word_disparity
[
ii
-
1
]
:
~
word_disparity
[
ii
-
1
])
;
// if there're 5 '1's - do no change the disparity, 6 or 4 - change
assign
six
[
ii
]
=
iword
[
ii
][
4
:
0
]
==
5'b00000
?
(
~
word_disparity
[
ii
]
?
6'b100111
:
6'b011000
)
:
iword
[
ii
][
4
:
0
]
==
5'b00001
?
(
~
word_disparity
[
ii
]
?
6'b011101
:
6'b100010
)
:
iword
[
ii
][
4
:
0
]
==
5'b00010
?
(
~
word_disparity
[
ii
]
?
6'b101101
:
6'b010010
)
...
...
@@ -684,7 +686,7 @@ begin: encode_by_word
:
iword
[
ii
][
7
:
5
]
==
3'd4
?
(
~
interm_disparity
[
ii
]
?
4'b1101
:
4'b0010
)
:
iword
[
ii
][
7
:
5
]
==
3'd5
?
(
~
interm_disparity
[
ii
]
?
4'b1010
:
4'b1010
)
:
iword
[
ii
][
7
:
5
]
==
3'd6
?
(
~
interm_disparity
[
ii
]
?
4'b0110
:
4'b0110
)
:
/*iword[ii][7:5] == 3'd7*/
(
~
interm_disparity
[
ii
]
?
(
six
[
ii
][
1
:
0
]
==
2'b
00
?
4'b1110
:
4'b0111
)
:
/*iword[ii][7:5] == 3'd7*/
(
~
interm_disparity
[
ii
]
?
(
six
[
ii
][
1
:
0
]
==
2'b
11
?
4'b0111
:
4'b1110
)
:
(
six
[
ii
][
1
:
0
]
==
2'b00
?
4'b1000
:
4'b0001
))
;
assign
oword
[
ii
]
=
~
is_control
[
ii
]
?
{
six
[
ii
]
,
four
[
ii
]
}
:
iword
[
ii
][
7
:
0
]
==
8'b00011100
?
(
~
word_disparity
[
ii
]
?
10'b0011110100
:
10'b1100001011
)
...
...
@@ -703,7 +705,7 @@ begin: encode_by_word
assign
data_out
[
ii
*
10
+
9
:
ii
*
10
]
=
oword
[
ii
]
;
end
endgenerate
assign
next_disparity
=
^
oword
[
word_count
-
1
]
?
~
word_disparity
[
word_count
-
1
]
:
word_disparity
[
word_count
-
1
]
;
assign
next_disparity
=
^
oword
[
word_count
-
1
]
?
word_disparity
[
word_count
-
1
]
:
~
word_disparity
[
word_count
-
1
]
;
endmodule
...
...
@@ -726,10 +728,10 @@ module gtxe2_chnl_tx_oob #(
parameter
[
3
:
0
]
SATA_BURST_SEQ_LEN
=
4'b0101
;
parameter
SATA_CPLL_CFG
=
"VCO_3000MHZ"
;
localparam
burst_len_mult
=
SATA_CPLL_CFG
==
"VCO_3000MHZ"
?
4
:
SATA_CPLL_CFG
==
"VCO_1500MHZ"
?
2
:
/* VCO_
750MHZ */
1
;
localparam
burst_len
=
burst_len_mult
*
8
;
// = 106.7ns; each burst contains 16 SATA Gen1 words
localparam
burst_len_mult
=
SATA_CPLL_CFG
==
"VCO_3000MHZ"
?
2
// assuming each usrclk cycle == 20 sata serial clk cycles
:
SATA_CPLL_CFG
==
"VCO_1500MHZ"
?
4
:
/* VCO_
6000MHZ */
1
;
localparam
burst_len
=
/*burst_len_mult * 8*/
32
;
// = 106.7ns; each burst contains 16 SATA Gen1 words
localparam
quiet_len_init
=
burst_len
*
3
;
// = 320ns
localparam
quiet_len_wake
=
burst_len
;
// = 106.7ns
localparam
init_bursts_cnt
=
SATA_BURST_SEQ_LEN
;
//3;
...
...
@@ -777,8 +779,8 @@ end
assign
set_burst
=
state_idle
&
(
TXCOMINIT
|
TXCOMWAKE
)
|
state_quiet
&
clr_quiet
&
~
TXCOMFINISH
;
assign
set_quiet
=
state_burst
&
(
bursts_cnt
<
bursts_cnt_togo
-
1
)
&
clr_burst
;
assign
clr_burst
=
state_burst
&
stopwatch
==
burst_len
;
assign
clr_quiet
=
state_quiet
&
stopwatch
==
quiet_len
;
assign
clr_burst
=
state_burst
&
stopwatch
==
(
burst_len
-
burst_len_mult
)
;
assign
clr_quiet
=
state_quiet
&
stopwatch
==
(
quiet_len
-
burst_len_mult
)
;
// bursts timing
assign
quiet_len
=
issued_wake
?
quiet_len_wake
:
quiet_len_init
;
...
...
@@ -808,6 +810,67 @@ assign TXCOMFINISH = bursts_cnt_clr & bursts_cnt == bursts_cnt_togo;
endmodule
/*
* According to the doc, p110
* If TX_INT_DATAWIDTH, the inner width = 32 bits, otherwise 16.
*/
module
gtxe2_chnl_tx_dataiface
#(
parameter
internal_data_width
=
16
,
parameter
interface_data_width
=
32
,
parameter
internal_isk_width
=
2
,
parameter
interface_isk_width
=
4
)
(
input
wire
usrclk
,
input
wire
usrclk2
,
input
wire
reset
,
output
wire
[
internal_data_width
-
1
:
0
]
outdata
,
output
wire
[
internal_isk_width
-
1
:
0
]
outisk
,
input
wire
[
interface_data_width
-
1
:
0
]
indata
,
input
wire
[
interface_isk_width
-
1
:
0
]
inisk
)
;
localparam
div
=
interface_data_width
/
internal_data_width
;
wire
[
interface_data_width
+
interface_isk_width
-
1
:
0
]
data_resynced
;
reg
[
31
:
0
]
wordcounter
;
wire
almost_empty_rd
;
wire
empty_rd
;
wire
full_wr
;
wire
val_rd
;
always
@
(
posedge
usrclk
)
wordcounter
<=
reset
|
wordcounter
==
(
div
-
1
)
?
32'h0
:
wordcounter
+
1'b1
;
assign
outdata
=
data_resynced
[(
wordcounter
+
1
)
*
internal_data_width
-
1
-:
internal_data_width
]
;
assign
outisk
=
data_resynced
[(
wordcounter
+
1
)
*
internal_isk_width
+
internal_data_width
*
div
-
1
-:
internal_isk_width
]
;
assign
val_rd
=
~
almost_empty_rd
&
~
empty_rd
&
wordcounter
==
(
div
-
1
)
;
resync_fifo_nonsynt
#(
.
width
(
interface_data_width
+
interface_isk_width
)
,
.
log_depth
(
3
)
)
fifo
(
.
rst_rd
(
reset
)
,
.
rst_wr
(
reset
)
,
.
clk_wr
(
usrclk2
)
,
.
val_wr
(
1'b1
)
,
.
data_wr
(
{
inisk
,
indata
}
)
,
.
clk_rd
(
usrclk
)
,
.
val_rd
(
val_rd
)
,
.
data_rd
(
{
data_resynced
}
)
,
.
empty_rd
(
empty_rd
)
,
.
full_wr
(
full_wr
)
,
.
almost_empty_rd
(
almost_empty_rd
)
)
;
endmodule
module
gtxe2_chnl_tx
(
input
wire
reset
,
output
wire
TXP
,
...
...
@@ -883,12 +946,15 @@ wire line_idle;
wire
line_idle_pcs
;
// line_idle in pcs clock domain
wire
[
internal_data_width
-
1
:
0
]
ser_input
;
wire
oob_active
;
reg
oob_in_process
;
always
@
(
posedge
TXUSRCLK
)
oob_in_process
<=
reset
|
TXCOMFINISH
?
1'b0
:
TXCOMINIT
|
TXCOMWAKE
?
1'b1
:
oob_in_process
;
assign
TXP
=
~
line_idle
?
serial_data
:
1'bx
;
assign
TXN
=
~
line_idle
?
~
serial_data
:
1'bx
;
assign
line_idle_pcs
=
TXELECIDLE
&
~
oob_active
|
reset
;
assign
line_idle_pcs
=
(
TXELECIDLE
|
oob_in_process
)
&
~
oob_active
|
reset
;
// Serializer
wire
[
internal_data_width
-
1
:
0
]
parallel_data
;
...
...
@@ -909,6 +975,35 @@ ser(
// TX PCS
// fit data width
// TODO make parameters awesome
localparam
data_width
=
16
;
localparam
if_data_width
=
32
;
localparam
isk_width
=
2
;
localparam
if_isk_width
=
4
;
wire
[
data_width
-
1
:
0
]
internal_data
;
wire
[
isk_width
-
1
:
0
]
internal_isk
;
gtxe2_chnl_tx_dataiface
#(
.
internal_data_width
(
data_width
)
,
.
interface_data_width
(
if_data_width
)
,
.
internal_isk_width
(
isk_width
)
,
.
interface_isk_width
(
if_isk_width
)
)
dataiface
(
.
usrclk
(
TXUSRCLK
)
,
.
usrclk2
(
TXUSRCLK2
)
,
.
reset
(
reset
)
,
.
outdata
(
internal_data
)
,
.
outisk
(
internal_isk
)
,
.
indata
(
TXDATA
[
if_data_width
-
1
:
0
])
,
.
inisk
(
TXCHARISK
[
if_isk_width
-
1
:
0
])
)
;
wire
[
internal_data_width
-
1
:
0
]
polarized_data
;
// invert data (get words as [abdceifghj] after 8/10, each word shall be transmitter in a reverse bit order)
genvar
ii
;
genvar
jj
;
...
...
@@ -923,7 +1018,6 @@ generate
endgenerate
// Polarity:
wire
[
internal_data_width
-
1
:
0
]
polarized_data
;
assign
ser_input
=
polarized_data
;
generate
...
...
@@ -941,7 +1035,9 @@ wire oob_val;
assign
oob_active
=
oob_val
;
gtxe2_chnl_tx_oob
#(
.
width
(
internal_data_width
)
.
width
(
internal_data_width
)
,
.
SATA_BURST_SEQ_LEN
(
SATA_BURST_SEQ_LEN
)
,
.
SATA_CPLL_CFG
(
SATA_CPLL_CFG
)
)
tx_oob
(
.
TXCOMINIT
(
TXCOMINIT
)
,
...
...
@@ -971,9 +1067,9 @@ encoder_8x10(
.
TX8B10BEN
(
TX8B10BEN
)
,
.
TXCHARDISPMODE
(
TXCHARDISPMODE
)
,
.
TXCHARDISPVAL
(
TXCHARDISPVAL
)
,
.
TXCHARISK
(
TXCHARISK
)
,
.
TXCHARISK
(
internal_isk
)
,
.
disparity
(
disparity
)
,
.
data_in
(
TXDATA
[
15
:
0
]
)
,
.
data_in
(
internal_data
)
,
.
data_out
(
encoded_data
)
,
.
next_disparity
(
next_disparity
)
)
;
...
...
@@ -1130,6 +1226,7 @@ module gtxe2_chnl_rx_oob #(
(
input
wire
reset
,
input
wire
clk
,
input
wire
usrclk2
,
input
wire
RXN
,
input
wire
RXP
,
...
...
@@ -1147,11 +1244,11 @@ localparam wake_idle_min_len = 150;
localparam
wake_idle_max_len
=
340
;
localparam
init_idle_min_len
=
450
;
localparam
init_idle_max_len
=
990
;
localparam
wake_bursts_cnt
=
5
;
localparam
init_bursts_cnt
=
5
;
localparam
wake_bursts_cnt
=
SATA_BURST_VAL
;
localparam
init_bursts_cnt
=
SATA_BURST_VAL
;
wire
idle
;
assign
idle
=
(
RXN
==
RXP
)
|
(
RXP
===
1'bx
)
;
assign
idle
=
(
RXN
==
RXP
)
|
(
RXP
===
1'bx
)
|
(
RXP
===
1'bz
)
;
wire
state_notrans
;
wire
state_error
;
//nostrans substate
...
...
@@ -1224,8 +1321,24 @@ assign done_init = state_burst & ~idle & bursts_cnt == (init_bursts_cnt - 1)&
assign
set_error
=
idle_len_violation
|
burst_len_violation
;
assign
set_done
=
~
set_error
&
(
done_wake
|
done_init
)
;
assign
RXCOMINITDET
=
done_init
;
assign
RXCOMWAKEDET
=
done_wake
;
// just to rxcominit(wake)det be synchronous to usrclk2
reg
rxcominitdet_clk
;
reg
rxcominitdet_usrclk2
;
reg
rxcomwakedet_clk
;
reg
rxcomwakedet_usrclk2
;
always
@
(
posedge
clk
)
begin
rxcominitdet_clk
<=
reset
?
1'b0
:
done_init
|
rxcominitdet_clk
&
~
rxcominitdet_usrclk2
;
rxcomwakedet_clk
<=
reset
?
1'b0
:
done_wake
|
rxcomwakedet_clk
&
~
rxcomwakedet_usrclk2
;
end
always
@
(
posedge
usrclk2
)
begin
rxcominitdet_usrclk2
<=
reset
?
1'b0
:
rxcominitdet_clk
&
~
rxcominitdet_usrclk2
;
rxcomwakedet_usrclk2
<=
reset
?
1'b0
:
rxcomwakedet_clk
&
~
rxcomwakedet_usrclk2
;
end
assign
RXCOMINITDET
=
rxcominitdet_usrclk2
;
assign
RXCOMWAKEDET
=
rxcomwakedet_usrclk2
;
assign
RXELECIDLE
=
RXP
===
1'bz
?
1'b1
:
RXP
===
1'bx
?
1'b1
:
RXP
==
RXN
;
endmodule
...
...
@@ -1438,6 +1551,8 @@ module gtxe2_chnl_rx_align #(
input
wire
[
width
-
1
:
0
]
indata
,
output
wire
[
width
-
1
:
0
]
outdata
,
input
wire
rxelecidle
,
output
wire
RXBYTEISALIGNED
,
output
wire
RXBYTEREALIGN
,
output
wire
RXCOMMADET
,
...
...
@@ -1461,6 +1576,29 @@ always @ (posedge clk)
// finding matches
wire
[
comma_width
-
1
:
0
]
comma_window
[
window_size
-
1
:
0
]
;
//initial
// for (idx = 0; idx < window_size; idx = idx + 1) $dumpvars(0, comma_width[idx]);
wire
[
comma_width
-
1
:
0
]
comma_window0
=
comma_window
[
0
]
;
wire
[
comma_width
-
1
:
0
]
comma_window1
=
comma_window
[
1
]
;
wire
[
comma_width
-
1
:
0
]
comma_window2
=
comma_window
[
2
]
;
wire
[
comma_width
-
1
:
0
]
comma_window3
=
comma_window
[
3
]
;
wire
[
comma_width
-
1
:
0
]
comma_window4
=
comma_window
[
4
]
;
wire
[
comma_width
-
1
:
0
]
comma_window5
=
comma_window
[
5
]
;
wire
[
comma_width
-
1
:
0
]
comma_window6
=
comma_window
[
6
]
;
wire
[
comma_width
-
1
:
0
]
comma_window7
=
comma_window
[
7
]
;
wire
[
comma_width
-
1
:
0
]
comma_window8
=
comma_window
[
8
]
;
wire
[
comma_width
-
1
:
0
]
comma_window9
=
comma_window
[
9
]
;
wire
[
comma_width
-
1
:
0
]
comma_window10
=
comma_window
[
10
]
;
wire
[
comma_width
-
1
:
0
]
comma_window11
=
comma_window
[
11
]
;
wire
[
comma_width
-
1
:
0
]
comma_window12
=
comma_window
[
12
]
;
wire
[
comma_width
-
1
:
0
]
comma_window13
=
comma_window
[
13
]
;
wire
[
comma_width
-
1
:
0
]
comma_window14
=
comma_window
[
14
]
;
wire
[
comma_width
-
1
:
0
]
comma_window15
=
comma_window
[
15
]
;
wire
[
comma_width
-
1
:
0
]
comma_window16
=
comma_window
[
16
]
;
wire
[
comma_width
-
1
:
0
]
comma_window17
=
comma_window
[
17
]
;
wire
[
comma_width
-
1
:
0
]
comma_window18
=
comma_window
[
18
]
;
wire
[
comma_width
-
1
:
0
]
comma_window19
=
comma_window
[
19
]
;
wire
[
window_size
-
1
:
0
]
comma_match
;
// shows all matches
wire
[
window_size
-
1
:
0
]
comma_pos
;
// shows the first match
wire
[
window_size
-
1
:
0
]
pcomma_match
;
...
...
@@ -1537,12 +1675,101 @@ assign RXBYTEREALIGN = RXCOMMADETEN & is_aligned & pointer_set;
always
@
(
posedge
clk
)
begin
is_aligned
<=
rst
?
1'b0
:
~
is_aligned
&
pointer_set
|
is_aligned
;
is_aligned
<=
rst
|
pointer_set
===
1'bx
|
rxelecidle
?
1'b0
:
~
is_aligned
&
pointer_set
|
is_aligned
;
pointer_latched
<=
rst
?
1'b0
:
pointer_set
?
pointer
:
pointer_latched
;
end
endmodule
/*
* According to the doc, p110
* If RX_INT_DATAWIDTH, the inner width = 32 bits, otherwise 16.
*/
module
gtxe2_chnl_rx_dataiface
#(
parameter
internal_data_width
=
16
,
parameter
interface_data_width
=
32
,
parameter
internal_isk_width
=
2
,
parameter
interface_isk_width
=
4
)
(
input
wire
usrclk
,
input
wire
usrclk2
,
input
wire
reset
,
output
wire
[
interface_data_width
-
1
:
0
]
outdata
,
output
wire
[
interface_isk_width
-
1
:
0
]
outisk
,
input
wire
[
internal_data_width
-
1
:
0
]
indata
,
input
wire
[
internal_isk_width
-
1
:
0
]
inisk
,
input
wire
realign
)
;
localparam
div
=
interface_data_width
/
internal_data_width
;
localparam
internal_total_width
=
internal_data_width
+
internal_isk_width
;
localparam
interface_total_width
=
interface_data_width
+
interface_isk_width
;
reg
[
interface_data_width
-
1
:
0
]
inbuffer_data
;
reg
[
interface_isk_width
-
1
:
0
]
inbuffer_isk
;
reg
[
31
:
0
]
wordcounter
;
wire
empty_rd
;
wire
full_wr
;
wire
val_wr
;
wire
val_rd
;
always
@
(
posedge
usrclk
)
wordcounter
<=
reset
?
32'h0
:
realign
&
~
(
div
==
0
)
?
31'b1
:
wordcounter
==
(
div
-
1
)
?
32'h0
:
wordcounter
+
1'b1
;
genvar
ii
;
generate
for
(
ii
=
0
;
ii
<
div
;
ii
=
ii
+
1
)
begin:
splicing
always
@
(
posedge
usrclk
)
inbuffer_data
[(
ii
+
1
)
*
internal_data_width
-
1
-:
internal_data_width
]
<=
reset
?
{
interface_data_width
{
1'b0
}}
:
((
wordcounter
==
ii
)
|
realign
&
(
0
==
ii
))
?
indata
:
inbuffer_data
[(
ii
+
1
)
*
internal_data_width
-
1
-:
internal_data_width
]
;
end
endgenerate
generate
for
(
ii
=
0
;
ii
<
div
;
ii
=
ii
+
1
)
begin:
splicing2
always
@
(
posedge
usrclk
)
inbuffer_isk
[(
ii
+
1
)
*
internal_isk_width
-
1
-:
internal_isk_width
]
<=
reset
?
{
interface_isk_width
{
1'b0
}}
:
((
wordcounter
==
ii
)
|
realign
&
(
0
==
ii
))
?
inisk
:
inbuffer_isk
[(
ii
+
1
)
*
internal_isk_width
-
1
-:
internal_isk_width
]
;
end
endgenerate
assign
val_rd
=
~
empty_rd
&
~
almost_empty_rd
;
assign
val_wr
=
~
full_wr
&
wordcounter
==
(
div
-
1
)
;
always
@
(
posedge
usrclk
)
if
(
full_wr
)
begin
$
display
(
"FIFO in %m is full, that is not an appropriate behaviour"
)
;
$
finish
;
end
wire
[
interface_total_width
-
1
:
0
]
resync
;
assign
outdata
=
resync
[
interface_data_width
-
1
:
0
]
;
assign
outisk
=
resync
[
interface_data_width
+
interface_isk_width
-
1
:
interface_data_width
]
;
resync_fifo_nonsynt
#(
.
width
(
interface_total_width
)
,
.
log_depth
(
3
)
)
fifo
(
.
rst_rd
(
reset
)
,
.
rst_wr
(
reset
)
,
.
clk_wr
(
usrclk2
)
,
.
val_wr
(
val_wr
)
,
.
data_wr
(
{
inisk
,
inbuffer_isk
[
interface_isk_width
-
internal_isk_width
-
1
:
0
]
,
indata
,
inbuffer_data
[
interface_data_width
-
internal_data_width
-
1
:
0
]
}
)
,
.
clk_rd
(
usrclk2
)
,
.
val_rd
(
val_rd
)
,
.
data_rd
(
resync
)
,
.
empty_rd
(
empty_rd
)
,
.
full_wr
(
full_wr
)
,
.
almost_empty_rd
(
almost_empty_rd
)
)
;
endmodule
module
gtxe2_chnl_rx
(
input
wire
reset
,
input
wire
RXP
,
...
...
@@ -1629,6 +1856,7 @@ gtxe2_chnl_rx_oob #(
rx_oob
(
.
reset
(
reset
)
,
.
clk
(
serial_clk
)
,
.
usrclk2
(
RXUSRCLK2
)
,
.
RXN
(
RXN
)
,
.
RXP
(
RXP
)
,
...
...
@@ -1676,6 +1904,8 @@ aligner(
.
indata
(
parallel_data
)
,
.
outdata
(
aligned_data
)
,
.
rxelecidle
(
RXELECIDLE
)
,
.
RXBYTEISALIGNED
(
RXBYTEISALIGNED
)
,
.
RXBYTEREALIGN
(
RXBYTEREALIGN
)
,
.
RXCOMMADET
(
RXCOMMADET
)
,
...
...
@@ -1685,6 +1915,8 @@ aligner(
.
RXMCOMMAALIGNEN
(
RXMCOMMAALIGNEN
)
)
;
wire
[
data_width
-
1
:
0
]
internal_data
;
wire
[
isk_width
-
1
:
0
]
internal_isk
;
// 10x8 decoder
gtxe2_chnl_rx_10x8dec
#(
.
iwidth
(
internal_data_width
)
,
...
...
@@ -1699,14 +1931,43 @@ decoder_10x8(
.
RX8B10BEN
(
RX8B10BEN
)
,
.
RXCHARISCOMMA
(
RXCHARISCOMMA
)
,
.
RXCHARISK
(
RXCHARISK
)
,
.
RXCHARISK
(
internal_isk
)
,
.
RXDISPERR
(
RXDISPERR
)
,
.
RXNOTINTABLE
(
RXNOTINTABLE
)
,
.
outdata
()
,
.
RXDATA
(
RXDATA
)
.
RXDATA
(
internal_data
)
)
;
// fit data width
// TODO make parameters awesome
localparam
data_width
=
16
;
localparam
if_data_width
=
32
;
localparam
isk_width
=
2
;
localparam
if_isk_width
=
4
;
gtxe2_chnl_rx_dataiface
#(
.
internal_data_width
(
data_width
)
,
.
interface_data_width
(
if_data_width
)
,
.
internal_isk_width
(
isk_width
)
,
.
interface_isk_width
(
if_isk_width
)
)
dataiface
(
.
usrclk
(
RXUSRCLK
)
,
.
usrclk2
(
RXUSRCLK2
)
,
.
reset
(
reset
)
,
.
indata
(
internal_data
)
,
.
inisk
(
internal_isk
)
,
.
outdata
(
RXDATA
[
if_data_width
-
1
:
0
])
,
.
outisk
(
RXCHARISK
[
if_isk_width
-
1
:
0
])
,
.
realign
(
RXBYTEREALIGN
===
1'bx
?
1'b0
:
RXBYTEREALIGN
)
)
;
assign
RXDATA
[
63
:
if_data_width
]
=
0
;
assign
RXCHARISK
[
7
:
if_isk_width
]
=
0
;
endmodule
module
gtxe2_chnl
(
...
...
@@ -1805,6 +2066,7 @@ module gtxe2_chnl(
input
wire
[
2
:
0
]
TXOUTCLKSEL
,
input
wire
[
2
:
0
]
RXOUTCLKSEL
,
input
wire
TXDLYBYPASS
,
input
wire
RXDLYBYPASS
,
output
wire
GTREFCLKMONITOR
,
input
wire
CPLLLOCKDETCLK
,
...
...
@@ -1963,11 +2225,6 @@ gtxe2_chnl_clocking #(
.
SATA_CPLL_CFG
(
SATA_CPLL_CFG
)
,
.
PMA_RSV3
(
PMA_RSV3
)
,
.
TXOUT_DIV
(
TXOUT_DIV
)
,
// .TXRATE (TXRATE),
.
RXOUT_DIV
(
RXOUT_DIV
)
,
// .RXRATE (RXRATE),
.
TX_INT_DATAWIDTH
(
TX_INT_DATAWIDTH
)
,
.
TX_DATA_WIDTH
(
TX_DATA_WIDTH
)
,
.
RX_INT_DATAWIDTH
(
RX_INT_DATAWIDTH
)
,
...
...
@@ -1989,6 +2246,7 @@ clocking(
.
TXOUTCLKSEL
(
TXOUTCLKSEL
)
,
.
RXOUTCLKSEL
(
RXOUTCLKSEL
)
,
.
TXDLYBYPASS
(
TXDLYBYPASS
)
,
.
RXDLYBYPASS
(
RXDLYBYPASS
)
,
.
GTREFCLKMONITOR
(
GTREFCLKMONITOR
)
,
.
CPLLLOCKDETCLK
(
CPLLLOCKDETCLK
)
,
...
...
@@ -2080,13 +2338,13 @@ module GTXE2_CHANNEL(
input
[
8
:
0
]
DRPADDR
,
input
DRPCLK
,
input
[
15
:
0
]
DRPDI
,
input
[
15
:
0
]
DRPDO
,
output
[
15
:
0
]
DRPDO
,
input
DRPEN
,
output
DRPRDY
,
input
DRPWE
,
// Digital Monitor Ports, ug476 p.95
input
[
3
:
0
]
CLKRSVD
,
input
[
7
:
0
]
DMONITOROUT
,
output
[
7
:
0
]
DMONITOROUT
,
// TX Interface Ports, ug476 p.110
input
[
7
:
0
]
TXCHARDISPMODE
,
input
[
7
:
0
]
TXCHARDISPVAL
,
...
...
@@ -2103,7 +2361,7 @@ module GTXE2_CHANNEL(
input
[
6
:
0
]
TXSEQUENCE
,
input
TXSTARTSEQ
,
// TX BUffer Ports, ug476 p.134
input
[
1
:
0
]
TXBUFSTATUS
,
output
[
1
:
0
]
TXBUFSTATUS
,
// TX Buffer Bypass Ports, ug476 p.136
input
TXDLYSRESET
,
input
TXPHALIGN
,
...
...
@@ -2123,8 +2381,8 @@ module GTXE2_CHANNEL(
input
TXSYNCMODE
,
input
TXSYNCALLIN
,
input
TXSYNCIN
,
input
TXSYNCOUT
,
input
TXSYNCDONE
,
output
TXSYNCOUT
,
output
TXSYNCDONE
,
// TX Pattern Generator, ug476 p.147
input
[
2
:
0
]
TXPRBSSEL
,
input
TXPRBSFORCEERR
,
...
...
@@ -2167,7 +2425,7 @@ module GTXE2_CHANNEL(
// TX Receiver Detection Ports, ug476 p.165
input
TXDETECTRX
,
output
PHYSTATUS
,
input
[
2
:
0
]
RXSTATUS
,
output
[
2
:
0
]
RXSTATUS
,
// TX OOB Signaling Ports, ug476 p.166
output
TXCOMFINISH
,
input
TXCOMINIT
,
...
...
@@ -2212,7 +2470,7 @@ module GTXE2_CHANNEL(
input
RXDFEXYDOVRDEN
,
input
RXDFEXYDEN
,
input
[
1
:
0
]
RXMONITORSEL
,
input
[
6
:
0
]
RXMONITOROUT
,
output
[
6
:
0
]
RXMONITOROUT
,
// CDR Ports, ug476 p.202
input
RXCDRHOLD
,
input
RXCDROVRDEN
,
...
...
@@ -2265,9 +2523,9 @@ module GTXE2_CHANNEL(
output
RXPHSLIPMONITOR
,
output
RXDLYSRESETDONE
,
// RX Buffer Ports, ug476 p.259
input
[
2
:
0
]
RXBUFSTATUS
,
output
[
2
:
0
]
RXBUFSTATUS
,
// RX Clock Correction Ports, ug476 p.263
input
[
1
:
0
]
RXCLKCORCNT
,
output
[
1
:
0
]
RXCLKCORCNT
,
// RX Channel Bonding Ports, ug476 p.274
output
RXCHANBONDSEQ
,
output
RXCHANISALIGNED
,
...
...
@@ -2281,7 +2539,7 @@ module GTXE2_CHANNEL(
// RX Gearbox Ports, ug476 p.285
output
RXDATAVALID
,
input
RXGEARBOXSLIP
,
input
[
2
:
0
]
RXHEADER
,
output
[
2
:
0
]
RXHEADER
,
output
RXHEADERVALID
,
output
RXSTARTOFSEQ
,
// FPGA RX Interface Ports, ug476 p.299
...
...
@@ -2551,7 +2809,17 @@ parameter RXGEARBOX_EN = "FALSE";
parameter
RX_CLK25_DIV
=
6
;
parameter
TX_CLK25_DIV
=
6
;
wire
reset
=
EYESCANRESET
|
RXCDRFREQRESET
|
RXCDRRESET
|
RXCDRRESETRSV
|
RXPRBSCNTRESET
|
RXBUFRESET
|
RXDLYSRESET
|
RXPHDLYRESET
|
RXDFELPMRESET
|
GTRXRESET
|
RXOOBRESET
|
RXPCSRESET
|
RXPMARESET
|
CFGRESET
|
GTTXRESET
|
GTRESETSEL
|
RESETOVRD
|
TXDLYSRESET
|
TXPHDLYRESET
|
TXPCSRESET
|
TXPMARESET
;
// clocking reset ( + TX PMA)
wire
clk_reset
=
EYESCANRESET
|
RXCDRFREQRESET
|
RXCDRRESET
|
RXCDRRESETRSV
|
RXPRBSCNTRESET
|
RXBUFRESET
|
RXDLYSRESET
|
RXPHDLYRESET
|
RXDFELPMRESET
|
GTRXRESET
|
RXOOBRESET
|
RXPCSRESET
|
RXPMARESET
|
CFGRESET
|
GTTXRESET
|
GTRESETSEL
|
RESETOVRD
|
TXDLYSRESET
|
TXPHDLYRESET
|
TXPCSRESET
|
TXPMARESET
;
// have to wait before an external pll (mmcm) locks with usrclk, after that PCS can be resetted. Actually, we reset PMA also, because why not
reg
reset
;
reg
[
31
:
0
]
reset_timer
=
0
;
always
@
(
posedge
TXUSRCLK
)
reset_timer
<=
~
TXUSERRDY
?
32'h0
:
reset_timer
==
32'hffffffff
?
reset_timer
:
reset_timer
+
1'b1
;
always
@
(
posedge
TXUSRCLK
)
reset
<=
~
TXUSERRDY
?
1'b0
:
reset_timer
<
32'd20
?
1'b1
:
1'b0
;
reg
rx_rst_done
=
1'b0
;
reg
tx_rst_done
=
1'b0
;
...
...
@@ -2588,11 +2856,6 @@ gtxe2_chnl #(
.
SATA_CPLL_CFG
(
SATA_CPLL_CFG
)
,
.
PMA_RSV3
(
PMA_RSV3
)
,
.
TXOUT_DIV
(
TXOUT_DIV
)
,
// .TXRATE (TXRATE),
.
RXOUT_DIV
(
RXOUT_DIV
)
,
// .RXRATE (RXRATE),
.
TX_INT_DATAWIDTH
(
TX_INT_DATAWIDTH
)
,
.
TX_DATA_WIDTH
(
TX_DATA_WIDTH
)
,
...
...
@@ -2614,8 +2877,7 @@ gtxe2_chnl #(
.
TX_INT_DATAWIDTH
(
TX_INT_DATAWIDTH
)
,
.
PTX8B10BEN
(
1
)
,
.
SATA_BURST_SEQ_LEN
(
SATA_BURST_SEQ_LEN
)
,
.
SATA_CPLL_CFG
(
SATA_CPLL_CFG
)
.
SATA_BURST_SEQ_LEN
(
SATA_BURST_SEQ_LEN
)
)
channel
(
.
reset
(
reset
)
,
...
...
gtxe2_channel/GTXE2_CHANNEL_GPL.v
View file @
9aabc22e
...
...
@@ -26,7 +26,7 @@
* Due to lack of functionality of gtxe2_gpl project as compared to the xilinx's primitive,
* not all of the inputs are used and not all of the outputs are driven.
**/
//
`include "gtxe2_chnl.v"
`include
"gtxe2_chnl.v"
module
GTXE2_CHANNEL
(
// clocking ports, UG476 p.37
input
[
2
:
0
]
CPLLREFCLKSEL
,
...
...
@@ -90,13 +90,13 @@ module GTXE2_CHANNEL(
input
[
8
:
0
]
DRPADDR
,
input
DRPCLK
,
input
[
15
:
0
]
DRPDI
,
input
[
15
:
0
]
DRPDO
,
output
[
15
:
0
]
DRPDO
,
input
DRPEN
,
output
DRPRDY
,
input
DRPWE
,
// Digital Monitor Ports, ug476 p.95
input
[
3
:
0
]
CLKRSVD
,
input
[
7
:
0
]
DMONITOROUT
,
output
[
7
:
0
]
DMONITOROUT
,
// TX Interface Ports, ug476 p.110
input
[
7
:
0
]
TXCHARDISPMODE
,
input
[
7
:
0
]
TXCHARDISPVAL
,
...
...
@@ -113,7 +113,7 @@ module GTXE2_CHANNEL(
input
[
6
:
0
]
TXSEQUENCE
,
input
TXSTARTSEQ
,
// TX BUffer Ports, ug476 p.134
input
[
1
:
0
]
TXBUFSTATUS
,
output
[
1
:
0
]
TXBUFSTATUS
,
// TX Buffer Bypass Ports, ug476 p.136
input
TXDLYSRESET
,
input
TXPHALIGN
,
...
...
@@ -133,8 +133,8 @@ module GTXE2_CHANNEL(
input
TXSYNCMODE
,
input
TXSYNCALLIN
,
input
TXSYNCIN
,
input
TXSYNCOUT
,
input
TXSYNCDONE
,
output
TXSYNCOUT
,
output
TXSYNCDONE
,
// TX Pattern Generator, ug476 p.147
input
[
2
:
0
]
TXPRBSSEL
,
input
TXPRBSFORCEERR
,
...
...
@@ -177,7 +177,7 @@ module GTXE2_CHANNEL(
// TX Receiver Detection Ports, ug476 p.165
input
TXDETECTRX
,
output
PHYSTATUS
,
input
[
2
:
0
]
RXSTATUS
,
output
[
2
:
0
]
RXSTATUS
,
// TX OOB Signaling Ports, ug476 p.166
output
TXCOMFINISH
,
input
TXCOMINIT
,
...
...
@@ -222,7 +222,7 @@ module GTXE2_CHANNEL(
input
RXDFEXYDOVRDEN
,
input
RXDFEXYDEN
,
input
[
1
:
0
]
RXMONITORSEL
,
input
[
6
:
0
]
RXMONITOROUT
,
output
[
6
:
0
]
RXMONITOROUT
,
// CDR Ports, ug476 p.202
input
RXCDRHOLD
,
input
RXCDROVRDEN
,
...
...
@@ -275,9 +275,9 @@ module GTXE2_CHANNEL(
output
RXPHSLIPMONITOR
,
output
RXDLYSRESETDONE
,
// RX Buffer Ports, ug476 p.259
input
[
2
:
0
]
RXBUFSTATUS
,
output
[
2
:
0
]
RXBUFSTATUS
,
// RX Clock Correction Ports, ug476 p.263
input
[
1
:
0
]
RXCLKCORCNT
,
output
[
1
:
0
]
RXCLKCORCNT
,
// RX Channel Bonding Ports, ug476 p.274
output
RXCHANBONDSEQ
,
output
RXCHANISALIGNED
,
...
...
@@ -291,7 +291,7 @@ module GTXE2_CHANNEL(
// RX Gearbox Ports, ug476 p.285
output
RXDATAVALID
,
input
RXGEARBOXSLIP
,
input
[
2
:
0
]
RXHEADER
,
output
[
2
:
0
]
RXHEADER
,
output
RXHEADERVALID
,
output
RXSTARTOFSEQ
,
// FPGA RX Interface Ports, ug476 p.299
...
...
@@ -561,7 +561,17 @@ parameter RXGEARBOX_EN = "FALSE";
parameter
RX_CLK25_DIV
=
6
;
parameter
TX_CLK25_DIV
=
6
;
wire
reset
=
EYESCANRESET
|
RXCDRFREQRESET
|
RXCDRRESET
|
RXCDRRESETRSV
|
RXPRBSCNTRESET
|
RXBUFRESET
|
RXDLYSRESET
|
RXPHDLYRESET
|
RXDFELPMRESET
|
GTRXRESET
|
RXOOBRESET
|
RXPCSRESET
|
RXPMARESET
|
CFGRESET
|
GTTXRESET
|
GTRESETSEL
|
RESETOVRD
|
TXDLYSRESET
|
TXPHDLYRESET
|
TXPCSRESET
|
TXPMARESET
;
// clocking reset ( + TX PMA)
wire
clk_reset
=
EYESCANRESET
|
RXCDRFREQRESET
|
RXCDRRESET
|
RXCDRRESETRSV
|
RXPRBSCNTRESET
|
RXBUFRESET
|
RXDLYSRESET
|
RXPHDLYRESET
|
RXDFELPMRESET
|
GTRXRESET
|
RXOOBRESET
|
RXPCSRESET
|
RXPMARESET
|
CFGRESET
|
GTTXRESET
|
GTRESETSEL
|
RESETOVRD
|
TXDLYSRESET
|
TXPHDLYRESET
|
TXPCSRESET
|
TXPMARESET
;
// have to wait before an external pll (mmcm) locks with usrclk, after that PCS can be resetted. Actually, we reset PMA also, because why not
reg
reset
;
reg
[
31
:
0
]
reset_timer
=
0
;
always
@
(
posedge
TXUSRCLK
)
reset_timer
<=
~
TXUSERRDY
?
32'h0
:
reset_timer
==
32'hffffffff
?
reset_timer
:
reset_timer
+
1'b1
;
always
@
(
posedge
TXUSRCLK
)
reset
<=
~
TXUSERRDY
?
1'b0
:
reset_timer
<
32'd20
?
1'b1
:
1'b0
;
reg
rx_rst_done
=
1'b0
;
reg
tx_rst_done
=
1'b0
;
...
...
@@ -598,11 +608,6 @@ gtxe2_chnl #(
.
SATA_CPLL_CFG
(
SATA_CPLL_CFG
)
,
.
PMA_RSV3
(
PMA_RSV3
)
,
.
TXOUT_DIV
(
TXOUT_DIV
)
,
// .TXRATE (TXRATE),
.
RXOUT_DIV
(
RXOUT_DIV
)
,
// .RXRATE (RXRATE),
.
TX_INT_DATAWIDTH
(
TX_INT_DATAWIDTH
)
,
.
TX_DATA_WIDTH
(
TX_DATA_WIDTH
)
,
...
...
@@ -624,8 +629,7 @@ gtxe2_chnl #(
.
TX_INT_DATAWIDTH
(
TX_INT_DATAWIDTH
)
,
.
PTX8B10BEN
(
1
)
,
.
SATA_BURST_SEQ_LEN
(
SATA_BURST_SEQ_LEN
)
,
.
SATA_CPLL_CFG
(
SATA_CPLL_CFG
)
.
SATA_BURST_SEQ_LEN
(
SATA_BURST_SEQ_LEN
)
)
channel
(
.
reset
(
reset
)
,
...
...
gtxe2_channel/gtxe2_chnl.v
View file @
9aabc22e
...
...
@@ -18,9 +18,9 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
//
`include "gtxe2_chnl_clocking.v"
//
`include "gtxe2_chnl_tx.v"
//
`include "gtxe2_chnl_rx.v"
`include
"gtxe2_chnl_clocking.v"
`include
"gtxe2_chnl_tx.v"
`include
"gtxe2_chnl_rx.v"
module
gtxe2_chnl
(
input
wire
reset
,
/*
...
...
@@ -117,6 +117,7 @@ module gtxe2_chnl(
input
wire
[
2
:
0
]
TXOUTCLKSEL
,
input
wire
[
2
:
0
]
RXOUTCLKSEL
,
input
wire
TXDLYBYPASS
,
input
wire
RXDLYBYPASS
,
output
wire
GTREFCLKMONITOR
,
input
wire
CPLLLOCKDETCLK
,
...
...
@@ -275,11 +276,6 @@ gtxe2_chnl_clocking #(
.
SATA_CPLL_CFG
(
SATA_CPLL_CFG
)
,
.
PMA_RSV3
(
PMA_RSV3
)
,
.
TXOUT_DIV
(
TXOUT_DIV
)
,
// .TXRATE (TXRATE),
.
RXOUT_DIV
(
RXOUT_DIV
)
,
// .RXRATE (RXRATE),
.
TX_INT_DATAWIDTH
(
TX_INT_DATAWIDTH
)
,
.
TX_DATA_WIDTH
(
TX_DATA_WIDTH
)
,
.
RX_INT_DATAWIDTH
(
RX_INT_DATAWIDTH
)
,
...
...
@@ -301,6 +297,7 @@ clocking(
.
TXOUTCLKSEL
(
TXOUTCLKSEL
)
,
.
RXOUTCLKSEL
(
RXOUTCLKSEL
)
,
.
TXDLYBYPASS
(
TXDLYBYPASS
)
,
.
RXDLYBYPASS
(
RXDLYBYPASS
)
,
.
GTREFCLKMONITOR
(
GTREFCLKMONITOR
)
,
.
CPLLLOCKDETCLK
(
CPLLLOCKDETCLK
)
,
...
...
gtxe2_channel/gtxe2_chnl_clocking.v
View file @
9aabc22e
...
...
@@ -19,10 +19,10 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
//
`include "gtxe2_chnl_cpll_inmux.v"
//
`include "gtxe2_chnl_outclk_mux.v"
//
`include "gtxe2_chnl_cpll.v"
//
`include "clock_divider.v"
`include
"gtxe2_chnl_cpll_inmux.v"
`include
"gtxe2_chnl_outclk_mux.v"
`include
"gtxe2_chnl_cpll.v"
`include
"clock_divider.v"
module
gtxe2_chnl_clocking
(
// top-level interfaces
input
wire
[
2
:
0
]
CPLLREFCLKSEL
,
...
...
@@ -40,6 +40,7 @@ module gtxe2_chnl_clocking(
input
wire
[
2
:
0
]
TXOUTCLKSEL
,
input
wire
[
2
:
0
]
RXOUTCLKSEL
,
input
wire
TXDLYBYPASS
,
input
wire
RXDLYBYPASS
,
output
wire
GTREFCLKMONITOR
,
input
wire
CPLLLOCKDETCLK
,
...
...
@@ -147,6 +148,7 @@ tx_toserialclk_div(
.
div
(
tx_serial_divider
)
)
;
wire
rx_sipo_clk
;
clock_divider
#(
// .divide_by (rx_serial_divider),
.
divide_by_param
(
0
)
...
...
gtxe2_channel/gtxe2_chnl_cpll.v
View file @
9aabc22e
...
...
@@ -18,7 +18,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
//
`include "gtxe2_chnl_cpll_def.v"
`include
"gtxe2_chnl_cpll_def.v"
module
gtxe2_chnl_cpll
(
// top-level interfaces
input
wire
CPLLLOCKDETCLK
,
...
...
gtxe2_channel/gtxe2_chnl_rx.v
View file @
9aabc22e
...
...
@@ -21,10 +21,11 @@
/**
* For now contains only deserializer, oob, 10x8 decoder, aligner and polarity invertor blocks
**/
//`include "gtxe2_chnl_rx_des.v"
//`include "gtxe2_chnl_rx_oob.v"
//`include "gtxe2_chnl_rx_10x8dec.v"
//`include "gtxe2_chnl_rx_align.v"
`include
"gtxe2_chnl_rx_des.v"
`include
"gtxe2_chnl_rx_oob.v"
`include
"gtxe2_chnl_rx_10x8dec.v"
`include
"gtxe2_chnl_rx_align.v"
`include
"gtxe2_chnl_rx_dataiface.v"
module
gtxe2_chnl_rx
(
input
wire
reset
,
input
wire
RXP
,
...
...
@@ -111,6 +112,7 @@ gtxe2_chnl_rx_oob #(
rx_oob
(
.
reset
(
reset
)
,
.
clk
(
serial_clk
)
,
.
usrclk2
(
RXUSRCLK2
)
,
.
RXN
(
RXN
)
,
.
RXP
(
RXP
)
,
...
...
@@ -158,6 +160,8 @@ aligner(
.
indata
(
parallel_data
)
,
.
outdata
(
aligned_data
)
,
.
rxelecidle
(
RXELECIDLE
)
,
.
RXBYTEISALIGNED
(
RXBYTEISALIGNED
)
,
.
RXBYTEREALIGN
(
RXBYTEREALIGN
)
,
.
RXCOMMADET
(
RXCOMMADET
)
,
...
...
@@ -167,6 +171,8 @@ aligner(
.
RXMCOMMAALIGNEN
(
RXMCOMMAALIGNEN
)
)
;
wire
[
data_width
-
1
:
0
]
internal_data
;
wire
[
isk_width
-
1
:
0
]
internal_isk
;
// 10x8 decoder
gtxe2_chnl_rx_10x8dec
#(
.
iwidth
(
internal_data_width
)
,
...
...
@@ -181,12 +187,41 @@ decoder_10x8(
.
RX8B10BEN
(
RX8B10BEN
)
,
.
RXCHARISCOMMA
(
RXCHARISCOMMA
)
,
.
RXCHARISK
(
RXCHARISK
)
,
.
RXCHARISK
(
internal_isk
)
,
.
RXDISPERR
(
RXDISPERR
)
,
.
RXNOTINTABLE
(
RXNOTINTABLE
)
,
.
outdata
()
,
.
RXDATA
(
RXDATA
)
.
RXDATA
(
internal_data
)
)
;
// fit data width
// TODO make parameters awesome
localparam
data_width
=
16
;
localparam
if_data_width
=
32
;
localparam
isk_width
=
2
;
localparam
if_isk_width
=
4
;
gtxe2_chnl_rx_dataiface
#(
.
internal_data_width
(
data_width
)
,
.
interface_data_width
(
if_data_width
)
,
.
internal_isk_width
(
isk_width
)
,
.
interface_isk_width
(
if_isk_width
)
)
dataiface
(
.
usrclk
(
RXUSRCLK
)
,
.
usrclk2
(
RXUSRCLK2
)
,
.
reset
(
reset
)
,
.
indata
(
internal_data
)
,
.
inisk
(
internal_isk
)
,
.
outdata
(
RXDATA
[
if_data_width
-
1
:
0
])
,
.
outisk
(
RXCHARISK
[
if_isk_width
-
1
:
0
])
,
.
realign
(
RXBYTEREALIGN
===
1'bx
?
1'b0
:
RXBYTEREALIGN
)
)
;
assign
RXDATA
[
63
:
if_data_width
]
=
0
;
assign
RXCHARISK
[
7
:
if_isk_width
]
=
0
;
endmodule
gtxe2_channel/gtxe2_chnl_rx_align.v
View file @
9aabc22e
...
...
@@ -34,6 +34,8 @@ module gtxe2_chnl_rx_align #(
input
wire
[
width
-
1
:
0
]
indata
,
output
wire
[
width
-
1
:
0
]
outdata
,
input
wire
rxelecidle
,
output
wire
RXBYTEISALIGNED
,
output
wire
RXBYTEREALIGN
,
output
wire
RXCOMMADET
,
...
...
@@ -57,6 +59,29 @@ always @ (posedge clk)
// finding matches
wire
[
comma_width
-
1
:
0
]
comma_window
[
window_size
-
1
:
0
]
;
//initial
// for (idx = 0; idx < window_size; idx = idx + 1) $dumpvars(0, comma_width[idx]);
wire
[
comma_width
-
1
:
0
]
comma_window0
=
comma_window
[
0
]
;
wire
[
comma_width
-
1
:
0
]
comma_window1
=
comma_window
[
1
]
;
wire
[
comma_width
-
1
:
0
]
comma_window2
=
comma_window
[
2
]
;
wire
[
comma_width
-
1
:
0
]
comma_window3
=
comma_window
[
3
]
;
wire
[
comma_width
-
1
:
0
]
comma_window4
=
comma_window
[
4
]
;
wire
[
comma_width
-
1
:
0
]
comma_window5
=
comma_window
[
5
]
;
wire
[
comma_width
-
1
:
0
]
comma_window6
=
comma_window
[
6
]
;
wire
[
comma_width
-
1
:
0
]
comma_window7
=
comma_window
[
7
]
;
wire
[
comma_width
-
1
:
0
]
comma_window8
=
comma_window
[
8
]
;
wire
[
comma_width
-
1
:
0
]
comma_window9
=
comma_window
[
9
]
;
wire
[
comma_width
-
1
:
0
]
comma_window10
=
comma_window
[
10
]
;
wire
[
comma_width
-
1
:
0
]
comma_window11
=
comma_window
[
11
]
;
wire
[
comma_width
-
1
:
0
]
comma_window12
=
comma_window
[
12
]
;
wire
[
comma_width
-
1
:
0
]
comma_window13
=
comma_window
[
13
]
;
wire
[
comma_width
-
1
:
0
]
comma_window14
=
comma_window
[
14
]
;
wire
[
comma_width
-
1
:
0
]
comma_window15
=
comma_window
[
15
]
;
wire
[
comma_width
-
1
:
0
]
comma_window16
=
comma_window
[
16
]
;
wire
[
comma_width
-
1
:
0
]
comma_window17
=
comma_window
[
17
]
;
wire
[
comma_width
-
1
:
0
]
comma_window18
=
comma_window
[
18
]
;
wire
[
comma_width
-
1
:
0
]
comma_window19
=
comma_window
[
19
]
;
wire
[
window_size
-
1
:
0
]
comma_match
;
// shows all matches
wire
[
window_size
-
1
:
0
]
comma_pos
;
// shows the first match
wire
[
window_size
-
1
:
0
]
pcomma_match
;
...
...
@@ -133,7 +158,7 @@ assign RXBYTEREALIGN = RXCOMMADETEN & is_aligned & pointer_set;
always
@
(
posedge
clk
)
begin
is_aligned
<=
rst
?
1'b0
:
~
is_aligned
&
pointer_set
|
is_aligned
;
is_aligned
<=
rst
|
pointer_set
===
1'bx
|
rxelecidle
?
1'b0
:
~
is_aligned
&
pointer_set
|
is_aligned
;
pointer_latched
<=
rst
?
1'b0
:
pointer_set
?
pointer
:
pointer_latched
;
end
...
...
gtxe2_channel/gtxe2_chnl_rx_dataiface.v
0 → 100644
View file @
9aabc22e
/*******************************************************************************
* Module: gtxe2_chnl_rx_dataiface
* Date: 2015-07-06
* Author: Alexey
* Description: output data @ usrclk2 <- inner data @ usrclk, widths changes respectively
*
* Copyright (c) 2015 Elphel, Inc.
* gtxe2_chnl_rx_dataiface.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* gtxe2_chnl_rx_dataiface.v file 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
/*
* According to the doc, p110
* If RX_INT_DATAWIDTH, the inner width = 32 bits, otherwise 16.
*/
module
gtxe2_chnl_rx_dataiface
#(
parameter
internal_data_width
=
16
,
parameter
interface_data_width
=
32
,
parameter
internal_isk_width
=
2
,
parameter
interface_isk_width
=
4
)
(
input
wire
usrclk
,
input
wire
usrclk2
,
input
wire
reset
,
output
wire
[
interface_data_width
-
1
:
0
]
outdata
,
output
wire
[
interface_isk_width
-
1
:
0
]
outisk
,
input
wire
[
internal_data_width
-
1
:
0
]
indata
,
input
wire
[
internal_isk_width
-
1
:
0
]
inisk
,
input
wire
realign
)
;
localparam
div
=
interface_data_width
/
internal_data_width
;
localparam
internal_total_width
=
internal_data_width
+
internal_isk_width
;
localparam
interface_total_width
=
interface_data_width
+
interface_isk_width
;
reg
[
interface_data_width
-
1
:
0
]
inbuffer_data
;
reg
[
interface_isk_width
-
1
:
0
]
inbuffer_isk
;
reg
[
31
:
0
]
wordcounter
;
wire
empty_rd
;
wire
full_wr
;
wire
val_wr
;
wire
val_rd
;
always
@
(
posedge
usrclk
)
wordcounter
<=
reset
?
32'h0
:
realign
&
~
(
div
==
0
)
?
31'b1
:
wordcounter
==
(
div
-
1
)
?
32'h0
:
wordcounter
+
1'b1
;
genvar
ii
;
generate
for
(
ii
=
0
;
ii
<
div
;
ii
=
ii
+
1
)
begin:
splicing
always
@
(
posedge
usrclk
)
inbuffer_data
[(
ii
+
1
)
*
internal_data_width
-
1
-:
internal_data_width
]
<=
reset
?
{
interface_data_width
{
1'b0
}}
:
((
wordcounter
==
ii
)
|
realign
&
(
0
==
ii
))
?
indata
:
inbuffer_data
[(
ii
+
1
)
*
internal_data_width
-
1
-:
internal_data_width
]
;
end
endgenerate
generate
for
(
ii
=
0
;
ii
<
div
;
ii
=
ii
+
1
)
begin:
splicing2
always
@
(
posedge
usrclk
)
inbuffer_isk
[(
ii
+
1
)
*
internal_isk_width
-
1
-:
internal_isk_width
]
<=
reset
?
{
interface_isk_width
{
1'b0
}}
:
((
wordcounter
==
ii
)
|
realign
&
(
0
==
ii
))
?
inisk
:
inbuffer_isk
[(
ii
+
1
)
*
internal_isk_width
-
1
-:
internal_isk_width
]
;
end
endgenerate
assign
val_rd
=
~
empty_rd
&
~
almost_empty_rd
;
assign
val_wr
=
~
full_wr
&
wordcounter
==
(
div
-
1
)
;
always
@
(
posedge
usrclk
)
if
(
full_wr
)
begin
$
display
(
"FIFO in %m is full, that is not an appropriate behaviour"
)
;
$
finish
;
end
wire
[
interface_total_width
-
1
:
0
]
resync
;
assign
outdata
=
resync
[
interface_data_width
-
1
:
0
]
;
assign
outisk
=
resync
[
interface_data_width
+
interface_isk_width
-
1
:
interface_data_width
]
;
resync_fifo_nonsynt
#(
.
width
(
interface_total_width
)
,
.
log_depth
(
3
)
)
fifo
(
.
rst_rd
(
reset
)
,
.
rst_wr
(
reset
)
,
.
clk_wr
(
usrclk2
)
,
.
val_wr
(
val_wr
)
,
.
data_wr
(
{
inisk
,
inbuffer_isk
[
interface_isk_width
-
internal_isk_width
-
1
:
0
]
,
indata
,
inbuffer_data
[
interface_data_width
-
internal_data_width
-
1
:
0
]
}
)
,
.
clk_rd
(
usrclk2
)
,
.
val_rd
(
val_rd
)
,
.
data_rd
(
resync
)
,
.
empty_rd
(
empty_rd
)
,
.
full_wr
(
full_wr
)
,
.
almost_empty_rd
(
almost_empty_rd
)
)
;
endmodule
gtxe2_channel/gtxe2_chnl_rx_des.v
View file @
9aabc22e
...
...
@@ -18,7 +18,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
//
`include "resync_fifo_nonsynt.v"
`include
"resync_fifo_nonsynt.v"
module
gtxe2_chnl_rx_des
#(
parameter
[
31
:
0
]
width
=
20
)
...
...
gtxe2_channel/gtxe2_chnl_rx_oob.v
View file @
9aabc22e
...
...
@@ -36,6 +36,7 @@ module gtxe2_chnl_rx_oob #(
(
input
wire
reset
,
input
wire
clk
,
input
wire
usrclk2
,
input
wire
RXN
,
input
wire
RXP
,
...
...
@@ -53,11 +54,11 @@ localparam wake_idle_min_len = 150;
localparam
wake_idle_max_len
=
340
;
localparam
init_idle_min_len
=
450
;
localparam
init_idle_max_len
=
990
;
localparam
wake_bursts_cnt
=
5
;
localparam
init_bursts_cnt
=
5
;
localparam
wake_bursts_cnt
=
SATA_BURST_VAL
;
localparam
init_bursts_cnt
=
SATA_BURST_VAL
;
wire
idle
;
assign
idle
=
(
RXN
==
RXP
)
|
(
RXP
===
1'bx
)
;
assign
idle
=
(
RXN
==
RXP
)
|
(
RXP
===
1'bx
)
|
(
RXP
===
1'bz
)
;
wire
state_notrans
;
wire
state_error
;
//nostrans substate
...
...
@@ -130,7 +131,23 @@ assign done_init = state_burst & ~idle & bursts_cnt == (init_bursts_cnt - 1)&
assign
set_error
=
idle_len_violation
|
burst_len_violation
;
assign
set_done
=
~
set_error
&
(
done_wake
|
done_init
)
;
assign
RXCOMINITDET
=
done_init
;
assign
RXCOMWAKEDET
=
done_wake
;
// just to rxcominit(wake)det be synchronous to usrclk2
reg
rxcominitdet_clk
;
reg
rxcominitdet_usrclk2
;
reg
rxcomwakedet_clk
;
reg
rxcomwakedet_usrclk2
;
always
@
(
posedge
clk
)
begin
rxcominitdet_clk
<=
reset
?
1'b0
:
done_init
|
rxcominitdet_clk
&
~
rxcominitdet_usrclk2
;
rxcomwakedet_clk
<=
reset
?
1'b0
:
done_wake
|
rxcomwakedet_clk
&
~
rxcomwakedet_usrclk2
;
end
always
@
(
posedge
usrclk2
)
begin
rxcominitdet_usrclk2
<=
reset
?
1'b0
:
rxcominitdet_clk
&
~
rxcominitdet_usrclk2
;
rxcomwakedet_usrclk2
<=
reset
?
1'b0
:
rxcomwakedet_clk
&
~
rxcomwakedet_usrclk2
;
end
assign
RXCOMINITDET
=
rxcominitdet_usrclk2
;
assign
RXCOMWAKEDET
=
rxcomwakedet_usrclk2
;
assign
RXELECIDLE
=
RXP
===
1'bz
?
1'b1
:
RXP
===
1'bx
?
1'b1
:
RXP
==
RXN
;
endmodule
gtxe2_channel/gtxe2_chnl_tx.v
View file @
9aabc22e
...
...
@@ -19,9 +19,10 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
//`include "gtxe2_chnl_tx_ser.v"
//`include "gtxe2_chnl_tx_8x10enc.v"
//`include "gtxe2_chnl_tx_oob.v"
`include
"gtxe2_chnl_tx_ser.v"
`include
"gtxe2_chnl_tx_8x10enc.v"
`include
"gtxe2_chnl_tx_oob.v"
`include
"gtxe2_chnl_tx_dataiface.v"
module
gtxe2_chnl_tx
(
input
wire
reset
,
output
wire
TXP
,
...
...
@@ -97,12 +98,15 @@ wire line_idle;
wire
line_idle_pcs
;
// line_idle in pcs clock domain
wire
[
internal_data_width
-
1
:
0
]
ser_input
;
wire
oob_active
;
reg
oob_in_process
;
always
@
(
posedge
TXUSRCLK
)
oob_in_process
<=
reset
|
TXCOMFINISH
?
1'b0
:
TXCOMINIT
|
TXCOMWAKE
?
1'b1
:
oob_in_process
;
assign
TXP
=
~
line_idle
?
serial_data
:
1'bx
;
assign
TXN
=
~
line_idle
?
~
serial_data
:
1'bx
;
assign
line_idle_pcs
=
TXELECIDLE
&
~
oob_active
|
reset
;
assign
line_idle_pcs
=
(
TXELECIDLE
|
oob_in_process
)
&
~
oob_active
|
reset
;
// Serializer
wire
[
internal_data_width
-
1
:
0
]
parallel_data
;
...
...
@@ -123,6 +127,35 @@ ser(
// TX PCS
// fit data width
// TODO make parameters awesome
localparam
data_width
=
16
;
localparam
if_data_width
=
32
;
localparam
isk_width
=
2
;
localparam
if_isk_width
=
4
;
wire
[
data_width
-
1
:
0
]
internal_data
;
wire
[
isk_width
-
1
:
0
]
internal_isk
;
gtxe2_chnl_tx_dataiface
#(
.
internal_data_width
(
data_width
)
,
.
interface_data_width
(
if_data_width
)
,
.
internal_isk_width
(
isk_width
)
,
.
interface_isk_width
(
if_isk_width
)
)
dataiface
(
.
usrclk
(
TXUSRCLK
)
,
.
usrclk2
(
TXUSRCLK2
)
,
.
reset
(
reset
)
,
.
outdata
(
internal_data
)
,
.
outisk
(
internal_isk
)
,
.
indata
(
TXDATA
[
if_data_width
-
1
:
0
])
,
.
inisk
(
TXCHARISK
[
if_isk_width
-
1
:
0
])
)
;
wire
[
internal_data_width
-
1
:
0
]
polarized_data
;
// invert data (get words as [abdceifghj] after 8/10, each word shall be transmitter in a reverse bit order)
genvar
ii
;
genvar
jj
;
...
...
@@ -137,7 +170,6 @@ generate
endgenerate
// Polarity:
wire
[
internal_data_width
-
1
:
0
]
polarized_data
;
assign
ser_input
=
polarized_data
;
generate
...
...
@@ -155,7 +187,9 @@ wire oob_val;
assign
oob_active
=
oob_val
;
gtxe2_chnl_tx_oob
#(
.
width
(
internal_data_width
)
.
width
(
internal_data_width
)
,
.
SATA_BURST_SEQ_LEN
(
SATA_BURST_SEQ_LEN
)
,
.
SATA_CPLL_CFG
(
SATA_CPLL_CFG
)
)
tx_oob
(
.
TXCOMINIT
(
TXCOMINIT
)
,
...
...
@@ -185,9 +219,9 @@ encoder_8x10(
.
TX8B10BEN
(
TX8B10BEN
)
,
.
TXCHARDISPMODE
(
TXCHARDISPMODE
)
,
.
TXCHARDISPVAL
(
TXCHARDISPVAL
)
,
.
TXCHARISK
(
TXCHARISK
)
,
.
TXCHARISK
(
internal_isk
)
,
.
disparity
(
disparity
)
,
.
data_in
(
TXDATA
[
15
:
0
]
)
,
.
data_in
(
internal_data
)
,
.
data_out
(
encoded_data
)
,
.
next_disparity
(
next_disparity
)
)
;
...
...
gtxe2_channel/gtxe2_chnl_tx_8x10enc.v
View file @
9aabc22e
...
...
@@ -43,7 +43,7 @@ wire [word_count - 1:0] word_disparity;
wire
[
word_count
-
1
:
0
]
interm_disparity
;
wire
[
5
:
0
]
six
[
word_count
-
1
:
0
]
;
wire
[
3
:
0
]
four
[
word_count
-
1
:
0
]
;
wire
[
owidth
-
1
:
0
]
oword
[
word_count
-
1
:
0
]
;
wire
[
9
:
0
]
oword
[
word_count
-
1
:
0
]
;
wire
[
iwidth
-
1
:
0
]
iword
[
word_count
-
1
:
0
]
;
wire
[
word_count
-
1
:
0
]
is_control
;
...
...
@@ -58,7 +58,7 @@ begin: encode_by_word
assign
iword
[
ii
]
=
data_in
[
ii
*
8
+
7
:
ii
*
8
]
;
assign
interm_disparity
[
ii
]
=
^
six
[
ii
]
?
word_disparity
[
ii
]
:
~
word_disparity
[
ii
]
;
assign
word_disparity
[
ii
]
=
(
ii
==
0
)
?
disparity
:
(
^
oword
[
ii
-
1
]
?
~
word_disparity
[
ii
-
1
]
:
word_disparity
[
ii
-
1
])
;
(
^
oword
[
ii
-
1
]
?
word_disparity
[
ii
-
1
]
:
~
word_disparity
[
ii
-
1
])
;
// if there're 5 '1's - do no change the disparity, 6 or 4 - change
assign
six
[
ii
]
=
iword
[
ii
][
4
:
0
]
==
5'b00000
?
(
~
word_disparity
[
ii
]
?
6'b100111
:
6'b011000
)
:
iword
[
ii
][
4
:
0
]
==
5'b00001
?
(
~
word_disparity
[
ii
]
?
6'b011101
:
6'b100010
)
:
iword
[
ii
][
4
:
0
]
==
5'b00010
?
(
~
word_disparity
[
ii
]
?
6'b101101
:
6'b010010
)
...
...
@@ -98,7 +98,7 @@ begin: encode_by_word
:
iword
[
ii
][
7
:
5
]
==
3'd4
?
(
~
interm_disparity
[
ii
]
?
4'b1101
:
4'b0010
)
:
iword
[
ii
][
7
:
5
]
==
3'd5
?
(
~
interm_disparity
[
ii
]
?
4'b1010
:
4'b1010
)
:
iword
[
ii
][
7
:
5
]
==
3'd6
?
(
~
interm_disparity
[
ii
]
?
4'b0110
:
4'b0110
)
:
/*iword[ii][7:5] == 3'd7*/
(
~
interm_disparity
[
ii
]
?
(
six
[
ii
][
1
:
0
]
==
2'b
00
?
4'b1110
:
4'b0111
)
:
/*iword[ii][7:5] == 3'd7*/
(
~
interm_disparity
[
ii
]
?
(
six
[
ii
][
1
:
0
]
==
2'b
11
?
4'b0111
:
4'b1110
)
:
(
six
[
ii
][
1
:
0
]
==
2'b00
?
4'b1000
:
4'b0001
))
;
assign
oword
[
ii
]
=
~
is_control
[
ii
]
?
{
six
[
ii
]
,
four
[
ii
]
}
:
iword
[
ii
][
7
:
0
]
==
8'b00011100
?
(
~
word_disparity
[
ii
]
?
10'b0011110100
:
10'b1100001011
)
...
...
@@ -117,6 +117,6 @@ begin: encode_by_word
assign
data_out
[
ii
*
10
+
9
:
ii
*
10
]
=
oword
[
ii
]
;
end
endgenerate
assign
next_disparity
=
^
oword
[
word_count
-
1
]
?
~
word_disparity
[
word_count
-
1
]
:
word_disparity
[
word_count
-
1
]
;
assign
next_disparity
=
^
oword
[
word_count
-
1
]
?
word_disparity
[
word_count
-
1
]
:
~
word_disparity
[
word_count
-
1
]
;
endmodule
gtxe2_channel/gtxe2_chnl_tx_dataiface.v
0 → 100644
View file @
9aabc22e
/*******************************************************************************
* Module: gtxe2_chnl_tx_dataiface
* Date: 2015-07-06
* Author: Alexey
* Description: input data @ usrclk2 -> inner data @ usrclk, widths changes respectively
*
* Copyright (c) 2015 Elphel, Inc.
* gtxe2_chnl_tx_dataiface.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* gtxe2_chnl_tx_dataiface.v file 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
/*
* According to the doc, p110
* If TX_INT_DATAWIDTH, the inner width = 32 bits, otherwise 16.
*/
module
gtxe2_chnl_tx_dataiface
#(
parameter
internal_data_width
=
16
,
parameter
interface_data_width
=
32
,
parameter
internal_isk_width
=
2
,
parameter
interface_isk_width
=
4
)
(
input
wire
usrclk
,
input
wire
usrclk2
,
input
wire
reset
,
output
wire
[
internal_data_width
-
1
:
0
]
outdata
,
output
wire
[
internal_isk_width
-
1
:
0
]
outisk
,
input
wire
[
interface_data_width
-
1
:
0
]
indata
,
input
wire
[
interface_isk_width
-
1
:
0
]
inisk
)
;
localparam
div
=
interface_data_width
/
internal_data_width
;
wire
[
interface_data_width
+
interface_isk_width
-
1
:
0
]
data_resynced
;
reg
[
31
:
0
]
wordcounter
;
wire
almost_empty_rd
;
wire
empty_rd
;
wire
full_wr
;
wire
val_rd
;
always
@
(
posedge
usrclk
)
wordcounter
<=
reset
|
wordcounter
==
(
div
-
1
)
?
32'h0
:
wordcounter
+
1'b1
;
assign
outdata
=
data_resynced
[(
wordcounter
+
1
)
*
internal_data_width
-
1
-:
internal_data_width
]
;
assign
outisk
=
data_resynced
[(
wordcounter
+
1
)
*
internal_isk_width
+
internal_data_width
*
div
-
1
-:
internal_isk_width
]
;
assign
val_rd
=
~
almost_empty_rd
&
~
empty_rd
&
wordcounter
==
(
div
-
1
)
;
resync_fifo_nonsynt
#(
.
width
(
interface_data_width
+
interface_isk_width
)
,
.
log_depth
(
3
)
)
fifo
(
.
rst_rd
(
reset
)
,
.
rst_wr
(
reset
)
,
.
clk_wr
(
usrclk2
)
,
.
val_wr
(
1'b1
)
,
.
data_wr
(
{
inisk
,
indata
}
)
,
.
clk_rd
(
usrclk
)
,
.
val_rd
(
val_rd
)
,
.
data_rd
(
{
data_resynced
}
)
,
.
empty_rd
(
empty_rd
)
,
.
full_wr
(
full_wr
)
,
.
almost_empty_rd
(
almost_empty_rd
)
)
;
endmodule
gtxe2_channel/gtxe2_chnl_tx_oob.v
View file @
9aabc22e
...
...
@@ -37,10 +37,10 @@ module gtxe2_chnl_tx_oob #(
parameter
[
3
:
0
]
SATA_BURST_SEQ_LEN
=
4'b0101
;
parameter
SATA_CPLL_CFG
=
"VCO_3000MHZ"
;
localparam
burst_len_mult
=
SATA_CPLL_CFG
==
"VCO_3000MHZ"
?
4
:
SATA_CPLL_CFG
==
"VCO_1500MHZ"
?
2
:
/* VCO_
750MHZ */
1
;
localparam
burst_len
=
burst_len_mult
*
8
;
// = 106.7ns; each burst contains 16 SATA Gen1 words
localparam
burst_len_mult
=
SATA_CPLL_CFG
==
"VCO_3000MHZ"
?
2
// assuming each usrclk cycle == 20 sata serial clk cycles
:
SATA_CPLL_CFG
==
"VCO_1500MHZ"
?
4
:
/* VCO_
6000MHZ */
1
;
localparam
burst_len
=
/*burst_len_mult * 8*/
32
;
// = 106.7ns; each burst contains 16 SATA Gen1 words
localparam
quiet_len_init
=
burst_len
*
3
;
// = 320ns
localparam
quiet_len_wake
=
burst_len
;
// = 106.7ns
localparam
init_bursts_cnt
=
SATA_BURST_SEQ_LEN
;
//3;
...
...
@@ -88,8 +88,8 @@ end
assign
set_burst
=
state_idle
&
(
TXCOMINIT
|
TXCOMWAKE
)
|
state_quiet
&
clr_quiet
&
~
TXCOMFINISH
;
assign
set_quiet
=
state_burst
&
(
bursts_cnt
<
bursts_cnt_togo
-
1
)
&
clr_burst
;
assign
clr_burst
=
state_burst
&
stopwatch
==
burst_len
;
assign
clr_quiet
=
state_quiet
&
stopwatch
==
quiet_len
;
assign
clr_burst
=
state_burst
&
stopwatch
==
(
burst_len
-
burst_len_mult
)
;
assign
clr_quiet
=
state_quiet
&
stopwatch
==
(
quiet_len
-
burst_len_mult
)
;
// bursts timing
assign
quiet_len
=
issued_wake
?
quiet_len_wake
:
quiet_len_init
;
...
...
gtxe2_channel/gtxe2_chnl_tx_ser.v
View file @
9aabc22e
...
...
@@ -18,7 +18,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
//
`include "resync_fifo_nonsynt.v"
`include
"resync_fifo_nonsynt.v"
module
gtxe2_chnl_tx_ser
#(
parameter
[
31
:
0
]
width
=
20
)
...
...
tb/tb.v
View file @
9aabc22e
...
...
@@ -19,8 +19,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
`timescale
1
ps
/
1
ps
//
`include "GTXE2_CHANNEL.v"
//
`include "test.v"
`include
"GTXE2_CHANNEL.v"
`include
"test.v"
module
tb
()
;
wire
reset
;
wire
TXP
;
...
...
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