Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
X
x393_sata
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
x393_sata
Commits
b2f9de10
Commit
b2f9de10
authored
Sep 14, 2015
by
Alexey Grebenkin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
regular commit
parent
e551876b
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
204 additions
and
84 deletions
+204
-84
sata_phy_dev.v
device/sata_phy_dev.v
+53
-11
dma_regs.v
dma/dma_regs.v
+1
-1
sata_top.v
dma/sata_top.v
+8
-8
top.v
dma/top.v
+4
-3
gtx_elastic.v
host/gtx_elastic.v
+10
-5
gtx_wrap.v
host/gtx_wrap.v
+62
-30
link.v
host/link.v
+35
-17
sata_phy.v
host/sata_phy.v
+19
-2
top_timing.xdc
synt/top_timing.xdc
+8
-6
test_top.v
tb/test_top.v
+4
-1
No files found.
device/sata_phy_dev.v
View file @
b2f9de10
...
...
@@ -292,13 +292,13 @@ ext_clock_buf(
GTXE2_CHANNEL
#(
.
SIM_RECEIVER_DETECT_PASS
(
"TRUE"
)
,
.
SIM_TX_EIDLE_DRIVE_LEVEL
(
"
X
"
)
,
.
SIM_TX_EIDLE_DRIVE_LEVEL
(
"
Z
"
)
,
.
SIM_RESET_SPEEDUP
(
"FALSE"
)
,
.
SIM_CPLLREFCLK_SEL
(
3'b001
)
,
.
SIM_VERSION
(
"4.0"
)
,
.
ALIGN_COMMA_DOUBLE
(
"FALSE"
)
,
.
ALIGN_COMMA_ENABLE
(
10'b1111111111
)
,
.
ALIGN_COMMA_WORD
(
1
)
,
.
ALIGN_COMMA_WORD
(
2
)
,
.
ALIGN_MCOMMA_DET
(
"TRUE"
)
,
.
ALIGN_MCOMMA_VALUE
(
10'b1010000011
)
,
.
ALIGN_PCOMMA_DET
(
"TRUE"
)
,
...
...
@@ -418,9 +418,9 @@ GTXE2_CHANNEL #(
.
PD_TRANS_TIME_TO_P2
(
8'h64
)
,
.
SAS_MAX_COM
(
64
)
,
.
SAS_MIN_COM
(
36
)
,
.
SATA_BURST_SEQ_LEN
(
4'b01
1
1
)
,
.
SATA_BURST_VAL
(
3'b1
1
0
)
,
.
SATA_EIDLE_VAL
(
3'b1
1
0
)
,
.
SATA_BURST_SEQ_LEN
(
4'b01
0
1
)
,
.
SATA_BURST_VAL
(
3'b1
0
0
)
,
.
SATA_EIDLE_VAL
(
3'b1
0
0
)
,
.
SATA_MAX_BURST
(
8
)
,
.
SATA_MAX_INIT
(
21
)
,
.
SATA_MAX_WAKE
(
7
)
,
...
...
@@ -729,13 +729,55 @@ gtx(
// align to 4-byte boundary
reg
twobytes_shift
;
reg
onebyte_shift
;
always
@
(
posedge
clk
)
twobytes_shift
<=
rst
?
1'b0
:
rxchariscomma_gtx
[
0
]
===
1'bx
?
1'b0
:
rxchariscomma_gtx
[
2
]
===
1'bx
?
1'b0
:
rxchariscomma_gtx
[
2
]
?
1'b1
:
rxchariscomma_gtx
[
0
]
?
1'b0
:
twobytes_shift
;
assign
rxdata
=
twobytes_shift
?
{
rxdata_gtx
[
63
:
32
]
,
rxdata_gtx
[
15
:
0
]
,
rxdata_gtx
[
31
:
16
]
}
:
rxdata_gtx
;
assign
rxcharisk
=
twobytes_shift
?
{
rxcharisk_gtx
[
7
:
4
]
,
rxcharisk_gtx
[
1
:
0
]
,
rxcharisk_gtx
[
3
:
2
]
}
:
rxcharisk_gtx
;
assign
rxchariscomma
=
twobytes_shift
?
{
rxchariscomma_gtx
[
7
:
4
]
,
rxchariscomma_gtx
[
1
:
0
]
,
rxchariscomma_gtx
[
3
:
2
]
}
:
rxchariscomma_gtx
;
assign
rxdisperr
=
twobytes_shift
?
{
rxdisperr_gtx
[
7
:
4
]
,
rxdisperr_gtx
[
1
:
0
]
,
rxdisperr_gtx
[
3
:
2
]
}
:
rxdisperr_gtx
;
assign
rxnotintable
=
twobytes_shift
?
{
rxnotintable_gtx
[
7
:
4
]
,
rxnotintable_gtx
[
1
:
0
]
,
rxnotintable_gtx
[
3
:
2
]
}
:
rxnotintable_gtx
;
twobytes_shift
<=
rst
?
1'b0
:
rxchariscomma_gtx
[
0
]
===
1'bx
|
rxchariscomma_gtx
[
1
]
===
1'bx
|
rxchariscomma_gtx
[
2
]
===
1'bx
|
rxchariscomma_gtx
[
3
]
===
1'bx
?
1'b0
:
rxchariscomma_gtx
[
2
]
|
rxchariscomma_gtx
[
3
]
?
1'b1
:
rxchariscomma_gtx
[
0
]
|
rxchariscomma_gtx
[
1
]
?
1'b0
:
twobytes_shift
;
always
@
(
posedge
clk
)
onebyte_shift
<=
rst
?
1'b0
:
rxchariscomma_gtx
[
0
]
===
1'bx
|
rxchariscomma_gtx
[
1
]
===
1'bx
|
rxchariscomma_gtx
[
2
]
===
1'bx
|
rxchariscomma_gtx
[
3
]
===
1'bx
?
1'b0
:
rxchariscomma_gtx
[
1
]
|
rxchariscomma_gtx
[
3
]
?
1'b1
:
rxchariscomma_gtx
[
0
]
|
rxchariscomma_gtx
[
2
]
?
1'b0
:
onebyte_shift
;
wire
[
31
:
0
]
shifted_rxdata
;
wire
[
7
:
0
]
shifted_rxcharisk
;
wire
[
7
:
0
]
shifted_rxchariscomma
;
wire
[
7
:
0
]
shifted_rxdisperr
;
wire
[
7
:
0
]
shifted_rxnotintable
;
wire
[
1
:
0
]
shift_val
=
{
twobytes_shift
,
onebyte_shift
};
reg
[
31
:
0
]
rxdata_gtx_r
;
reg
[
7
:
0
]
rxcharisk_gtx_r
;
reg
[
7
:
0
]
rxchariscomma_gtx_r
;
reg
[
7
:
0
]
rxdisperr_gtx_r
;
reg
[
7
:
0
]
rxnotintable_gtx_r
;
always
@
(
posedge
clk
)
begin
rxdata_gtx_r
<=
rxdata_gtx
[
31
:
0
]
;
rxcharisk_gtx_r
<=
rxcharisk_gtx
[
3
:
0
]
;
rxchariscomma_gtx_r
<=
rxchariscomma_gtx
[
3
:
0
]
;
rxdisperr_gtx_r
<=
rxdisperr_gtx
[
3
:
0
]
;
rxnotintable_gtx_r
<=
rxnotintable_gtx
[
3
:
0
]
;
end
wire
[
63
:
0
]
rxdata_d
=
{
rxdata_gtx
[
31
:
0
]
,
rxdata_gtx_r
[
31
:
0
]
};
wire
[
7
:
0
]
rxcharisk_d
=
{
rxcharisk_gtx
[
3
:
0
]
,
rxcharisk_gtx_r
[
3
:
0
]
};
wire
[
7
:
0
]
rxchariscomma_d
=
{
rxchariscomma_gtx
[
3
:
0
]
,
rxchariscomma_gtx_r
[
3
:
0
]
};
wire
[
7
:
0
]
rxdisperr_d
=
{
rxdisperr_gtx
[
3
:
0
]
,
rxdisperr_gtx_r
[
3
:
0
]
};
wire
[
7
:
0
]
rxnotintable_d
=
{
rxnotintable_gtx
[
3
:
0
]
,
rxnotintable_gtx_r
[
3
:
0
]
};
genvar
ii
;
generate
for
(
ii
=
0
;
ii
<
4
;
ii
=
ii
+
1
)
begin:
ads
assign
shifted_rxdata
[
ii
*
8
+
7
:
ii
*
8
]
=
shift_val
==
2'b11
?
rxdata_d
[(
ii
+
3
)
*
8
+
7
:
(
ii
+
3
)
*
8
]
:
shift_val
==
2'b10
?
rxdata_d
[(
ii
+
2
)
*
8
+
7
:
(
ii
+
2
)
*
8
]
:
shift_val
==
2'b01
?
rxdata_d
[(
ii
+
1
)
*
8
+
7
:
(
ii
+
1
)
*
8
]
:
rxdata_d
[
ii
*
8
+
7
:
ii
*
8
]
;
assign
shifted_rxcharisk
[
ii
]
=
shift_val
==
2'b11
?
rxcharisk_d
[(
ii
+
3
)]
:
shift_val
==
2'b10
?
rxcharisk_d
[(
ii
+
2
)]
:
shift_val
==
2'b01
?
rxcharisk_d
[(
ii
+
1
)]
:
rxcharisk_d
[
ii
]
;
assign
shifted_rxchariscomma
[
ii
]
=
shift_val
==
2'b11
?
rxchariscomma_d
[(
ii
+
3
)]
:
shift_val
==
2'b10
?
rxchariscomma_d
[(
ii
+
2
)]
:
shift_val
==
2'b01
?
rxchariscomma_d
[(
ii
+
1
)]
:
rxchariscomma_d
[
ii
]
;
assign
shifted_rxdisperr
[
ii
]
=
shift_val
==
2'b11
?
rxdisperr_d
[(
ii
+
3
)]
:
shift_val
==
2'b10
?
rxdisperr_d
[(
ii
+
2
)]
:
shift_val
==
2'b01
?
rxdisperr_d
[(
ii
+
1
)]
:
rxdisperr_d
[
ii
]
;
assign
shifted_rxnotintable
[
ii
]
=
shift_val
==
2'b11
?
rxnotintable_d
[(
ii
+
3
)]
:
shift_val
==
2'b10
?
rxnotintable_d
[(
ii
+
2
)]
:
shift_val
==
2'b01
?
rxnotintable_d
[(
ii
+
1
)]
:
rxnotintable_d
[
ii
]
;
end
endgenerate
assign
rxdata
=
{
rxdata_gtx
[
63
:
32
]
,
shifted_rxdata
};
assign
rxcharisk
=
{
rxcharisk_gtx
[
7
:
4
]
,
shifted_rxcharisk
};
assign
rxchariscomma
=
{
rxchariscomma_gtx
[
7
:
4
]
,
shifted_rxchariscomma
};
assign
rxdisperr
=
{
rxdisperr_gtx
[
7
:
4
]
,
shifted_rxdisperr
};
assign
rxnotintable
=
{
rxnotintable_gtx
[
7
:
4
]
,
shifted_rxnotintable
};
assign
ll_err_out
=
rxdisperr
[
3
:
0
]
|
rxnotintable
[
3
:
0
]
;
...
...
dma/dma_regs.v
View file @
b2f9de10
...
...
@@ -166,7 +166,7 @@ begin
reg04
<=
rst
?
32'h0
:
bram_wen
&
(
bram_waddr
[
7
:
0
]
==
8'hf1
)
?
wdata
:
reg04
;
reg08
<=
rst
?
32'h0
:
bram_wen
&
(
bram_waddr
[
7
:
0
]
==
8'hf2
)
?
wdata
:
reg08
;
reg0c
<=
rst
?
32'h0
:
bram_wen
&
(
bram_waddr
[
7
:
0
]
==
8'hf3
)
?
wdata
:
reg0c
;
reg10
<=
rst
?
32'h0
:
dma_start_aclk
?
32'h0
:
dma_done_aclk
?
32'hffffffff
:
reg10
;
// status reg
reg10
<=
rst
?
32'h0
:
dma_start_aclk
?
32'h0
:
{
31'h0
,
dma_done_aclk
}
?
32'hffffffff
:
reg10
;
// status reg
reg14
<=
rst
?
32'h0
:
dma_done_aclk
?
reg00
:
reg14
;
end
...
...
dma/sata_top.v
View file @
b2f9de10
...
...
@@ -36,6 +36,7 @@
// reliable clock to source drp and cpll lock det circuits
input
wire
reliable_clk
,
input
wire
hclk
,
/*
* Commands interface
*/
...
...
@@ -232,7 +233,7 @@ wire dma_type;
wire
dma_start
;
wire
dma_done
;
// axi-hp clock
wire
hclk
;
//
wire hclk;
// dma_control <-> dma_adapter command iface
wire
adp_busy
;
wire
[
31
:
7
]
adp_addr
;
...
...
@@ -283,10 +284,9 @@ wire [63:0] buf_rdata;
wire
rdata_done
;
// = membridge.is_last_in_page & membridge.afi_rready;
//assign rst = ARESETN;
// TODO
assign
hclk
=
ACLK
;
reg
hrst
;
always
@
(
posedge
hclk
)
hrst
<=
sata_rst
;
axi_regs
axi_regs
(
// axi iface
...
...
@@ -477,7 +477,7 @@ dma_control dma_control(
dma_adapter
dma_adapter
(
.
clk
(
hclk
)
,
.
rst
(
sata_
rst
)
,
.
rst
(
h
rst
)
,
// command iface
.
cmd_type
(
adp_type
)
,
.
cmd_val
(
adp_val
)
,
...
...
@@ -530,8 +530,8 @@ V .MEMBRIDGE_ADDR (),
.FRAME_HEIGHT_BITS (),
.FRAME_WIDTH_BITS ()
)*/
membridge
(
.
mrst
(
sata_
rst
)
,
// input
.
hrst
(
ARESETN
)
,
// input
.
mrst
(
h
rst
)
,
// input
.
hrst
(
hrst
)
,
// input
.
mclk
(
hclk
)
,
// input
.
hclk
(
hclk
)
,
// input
.
cmd_ad
(
cmd_ad
)
,
...
...
dma/top.v
View file @
b2f9de10
...
...
@@ -153,10 +153,11 @@ sata_top sata_top(
.
sclk
(
sclk
)
,
// reliable clock to source drp and cpll lock det circuits
.
reliable_clk
(
axi_aclk0
)
,
.
hclk
(
hclk
)
,
.
sata_rst
(
sata_rst
)
,
.
extrst
(
extrst
)
,
.
ACLK
(
axi_aclk
)
,
.
ARESETN
(
axi_rst
|
sata_rst
)
,
.
ACLK
(
axi_aclk
0
)
,
.
ARESETN
(
axi_rst
/* | sata_rst*/
)
,
// AXI PS Master GP1: Read Address
.
ARADDR
(
ARADDR
)
,
.
ARVALID
(
ARVALID
)
,
...
...
@@ -571,7 +572,7 @@ PS7 ps7_i (
// AXI PS Master GP1
// AXI PS Master GP1: Clock, Reset
.
MAXIGP1ACLK
(
axi_aclk
)
,
// AXI PS Master GP1 Clock , input
.
MAXIGP1ACLK
(
axi_aclk
0
)
,
// AXI PS Master GP1 Clock , input
.
MAXIGP1ARESETN
()
,
// AXI PS Master GP1 Reset, output
// AXI PS Master GP1: Read Address
.
MAXIGP1ARADDR
(
ARADDR
)
,
// AXI PS Master GP1 ARADDR[31:0], output
...
...
host/gtx_elastic.v
View file @
b2f9de10
...
...
@@ -64,7 +64,7 @@ localparam HI = DEPTH_LOG2 - 1; // hi bus index
reg
[
22
:
0
]
ram
[(
1
<<
DEPTH_LOG2
)
-
1
:
0
]
;
// data to/from fifo
wire
[
22
:
0
]
inram
;
wire
[
22
:
0
]
outram
;
reg
[
22
:
0
]
outram
;
// adresses in their natural clock domains
reg
[
HI
:
0
]
rd_addr
;
reg
[
HI
:
0
]
wr_addr
;
...
...
@@ -142,7 +142,8 @@ endgenerate
assign
full
=
wr_addr
==
rd_addr_r
+
1'b1
;
assign
empty
=
wr_addr_r
==
rd_addr
;
assign
outram
=
ram
[
rd_addr
]
;
always
@
(
posedge
rclk
)
outram
<=
ram
[
rd_addr
]
;
always
@
(
posedge
wclk
)
if
(
we
)
...
...
@@ -283,7 +284,7 @@ wire clr_skip2_align;
wire
clr_wait_next_p
;
wire
clr_send_ack
;
always
@
(
wclk
)
always
@
(
posedge
wclk
)
next_prim_loaded
<=
state_wait_next_p
;
assign
state_bypass_rmv
=
~
state_wait1_align
&
~
state_skip1_align
&
~
state_wait2_align
&
~
state_skip2_align
&
~
state_wait_next_p
&
~
state_send_ack
;
...
...
@@ -388,11 +389,15 @@ always @ (posedge rclk)
// choose 1 of 2 words of ALIGNP
wire
[
22
:
0
]
align_word
;
assign
align_word
=
{
outram
[
22
]
,
22'h007B4A
}
&
{
23
{
~
align_altern
}}
|
{
outram
[
22
]
,
22'h014ABC
}
&
{
23
{
align_altern
}};
assign
align_word
=
{
outram
[
22
]
,
22'h007B4A
}
&
{
23
{
align_altern
}}
|
{
outram
[
22
]
,
22'h014ABC
}
&
{
23
{~
align_altern
}};
// output data would be valid the next clock they are issued
reg
pause_read_r
;
always
@
(
posedge
rclk
)
pause_read_r
<=
pause_read
;
// read when compensation is not issued and when fifo gets required fullfillment
assign
re
=
~
pause_read
&
fifo_stable
;
assign
outdata
=
{
23
{~
pause_read
}}
&
outram
|
{
23
{
pause_read
}}
&
align_word
;
assign
outdata
=
{
23
{~
pause_read
_r
}}
&
outram
|
{
23
{
pause_read_r
}}
&
align_word
;
// indicates last cycle before the next primitive
wire
fword_strobe_correction
;
reg
fword_strobe
;
...
...
host/gtx_wrap.v
View file @
b2f9de10
...
...
@@ -75,11 +75,15 @@ module gtx_wrap #(
wire
rxresetdone_gtx
;
wire
txresetdone_gtx
;
wire
wrap_rxreset_
;
wire
wrap_txreset_
;
reg
rxresetdone_gtx_r
;
reg
txresetdone_gtx_r
;
reg
wrap_rxreset_
;
reg
wrap_txreset_
;
// resets while PCS resets, active low
assign
wrap_rxreset_
=
rxuserrdy
&
rxresetdone_gtx
;
assign
wrap_txreset_
=
txuserrdy
&
txresetdone_gtx
;
always
@
(
posedge
rxusrclk2
)
wrap_rxreset_
<=
rxuserrdy
&
rxresetdone_gtx_r
;
always
@
(
posedge
txusrclk2
)
wrap_txreset_
<=
txuserrdy
&
txresetdone_gtx_r
;
wire
[
63
:
0
]
rxdata_gtx
;
wire
[
7
:
0
]
rxcharisk_gtx
;
...
...
@@ -164,9 +168,19 @@ if (DATA_BYTE_WIDTH == 4) begin
.
half_empty
()
)
;
assign
txcomwake_gtx
=
txdata_resync_out
[
36
]
;
assign
txcominit_gtx
=
txdata_resync_out
[
37
]
;
assign
txelecidle_gtx
=
txdata_resync_out
[
38
]
;
reg
txcomwake_gtx_f
;
reg
txcominit_gtx_f
;
reg
txelecidle_gtx_f
;
always
@
(
posedge
txusrclk
)
begin
txcomwake_gtx_f
<=
txdata_resync_out
[
36
]
;
txcominit_gtx_f
<=
txdata_resync_out
[
37
]
;
txelecidle_gtx_f
<=
txdata_resync_out
[
38
]
;
end
assign
txcomwake_gtx
=
txcomwake_gtx_f
;
assign
txcominit_gtx
=
txcominit_gtx_f
;
assign
txelecidle_gtx
=
txelecidle_gtx_f
;
end
else
if
(
DATA_BYTE_WIDTH
==
2
)
begin
...
...
@@ -309,6 +323,8 @@ gtx_elastic(
*/
wire
rxcomwakedet_gtx
;
wire
rxcominitdet_gtx
;
reg
rxcomwakedet_gtx_r
;
reg
rxcominitdet_gtx_r
;
// insert resync if it's necessary
...
...
@@ -323,15 +339,15 @@ if (DATA_BYTE_WIDTH == 4) begin
wire
rxdata_resync_strobe
;
wire
[
50
:
0
]
rxdata_resync_in
;
wire
[
50
:
0
]
rxdata_resync_out
;
reg
[
2
3
:
0
]
rxdata_resync_buf
;
reg
[
2
5
:
0
]
rxdata_resync_buf
;
assign
rxdata_resync_strobe
=
lword_strobe
;
assign
rxdata_resync_in
=
{
isaligned
,
// 1
rxcomwakedet_gtx
,
// 1
rxcominitdet_gtx
,
// 1
rxresetdone_gtx
,
// 1
txresetdone_gtx
,
// 1
rxcomwakedet_gtx
_r
|
rxdata_resync_buf
[
25
]
,
// 1
rxcominitdet_gtx
_r
|
rxdata_resync_buf
[
24
]
,
// 1
rxresetdone_gtx
_r
,
// 1
txresetdone_gtx
_r
,
// 1
elastic_full
|
rxdata_resync_buf
[
23
]
,
// 1
elastic_empty
|
rxdata_resync_buf
[
22
]
,
// 1
rxdisperr_els_out
,
// 2
...
...
@@ -340,7 +356,7 @@ if (DATA_BYTE_WIDTH == 4) begin
rxdata_els_out
,
// 16
rxdata_resync_buf
[
21
:
0
]
};
// 22 / 51 total
always
@
(
posedge
rxusrclk
)
rxdata_resync_buf
<=
~
wrap_rxreset_
?
2
4'h0
:
~
rxdata_resync_strobe
?
{
elastic_full
,
elastic_empty
,
rxdisperr_els_out
,
rxnotintable_els_out
,
rxcharisk_els_out
,
rxdata_els_out
}
:
rxdata_resync_buf
;
rxdata_resync_buf
<=
~
wrap_rxreset_
?
2
6'h0
:
~
rxdata_resync_strobe
?
{
rxcomwakedet_gtx_r
,
rxcominitdet_gtx_r
,
elastic_full
,
elastic_empty
,
rxdisperr_els_out
,
rxnotintable_els_out
,
rxcharisk_els_out
,
rxdata_els_out
}
:
rxdata_resync_buf
;
always
@
(
posedge
rxusrclk2
)
rxdata_resync_nempty_r
<=
rxdata_resync_nempty
;
...
...
@@ -378,10 +394,10 @@ else
if
(
DATA_BYTE_WIDTH
==
2
)
begin
// no resync is needed => straightforward assignments
assign
rxbyteisaligned
=
isaligned
;
assign
rxcomwakedet
=
rxcomwakedet_gtx
;
assign
rxcominitdet
=
rxcominitdet_gtx
;
assign
rxresetdone
=
rxresetdone_gtx
;
assign
txresetdone
=
txresetdone_gtx
;
assign
rxcomwakedet
=
rxcomwakedet_gtx
_r
;
assign
rxcominitdet
=
rxcominitdet_gtx
_r
;
assign
rxresetdone
=
rxresetdone_gtx
_r
;
assign
txresetdone
=
txresetdone_gtx
_r
;
assign
rxelsfull
=
elastic_full
;
assign
rxelsempty
=
elastic_empty
;
assign
rxdisperr
[
1
:
0
]
=
rxdisperr_els_out
;
...
...
@@ -398,9 +414,25 @@ else begin
end
endgenerate
// latching gtx outputs, synchronous to RXUSRCLK2 = rxusrclk
always
@
(
posedge
rxusrclk
)
begin
rxcomwakedet_gtx_r
<=
rxcomwakedet_gtx
;
rxcominitdet_gtx_r
<=
rxcominitdet_gtx
;
rxresetdone_gtx_r
<=
rxresetdone_gtx
;
txresetdone_gtx_r
<=
txresetdone_gtx
;
end
wire
txoutclk_gtx
;
wire
xclk_gtx
;
wire
xclk_mr
;
BUFG
bufg_txoutclk
(
.
O
(
txoutclk
)
,.
I
(
txoutclk_gtx
))
;
BUFR
bufr_xclk
(
.
O
(
xclk
)
,.
I
(
xclk_mr
)
,.
CE
(
1'b1
)
,.
CLR
(
1'b0
))
;
BUFMR
bufmr_xclk
(
.
O
(
xclk_mr
)
,.
I
(
xclk_gtx
))
;
GTXE2_CHANNEL
#(
.
SIM_RECEIVER_DETECT_PASS
(
"TRUE"
)
,
.
SIM_TX_EIDLE_DRIVE_LEVEL
(
"
X
"
)
,
.
SIM_TX_EIDLE_DRIVE_LEVEL
(
"
Z
"
)
,
.
SIM_RESET_SPEEDUP
(
"FALSE"
)
,
.
SIM_CPLLREFCLK_SEL
(
3'b001
)
,
.
SIM_VERSION
(
"4.0"
)
,
...
...
@@ -527,8 +559,8 @@ GTXE2_CHANNEL #(
.
SAS_MAX_COM
(
64
)
,
.
SAS_MIN_COM
(
36
)
,
.
SATA_BURST_SEQ_LEN
(
4'b0110
)
,
.
SATA_BURST_VAL
(
3'b1
1
0
)
,
.
SATA_EIDLE_VAL
(
3'b1
1
0
)
,
.
SATA_BURST_VAL
(
3'b1
0
0
)
,
.
SATA_EIDLE_VAL
(
3'b1
0
0
)
,
.
SATA_MAX_BURST
(
8
)
,
.
SATA_MAX_INIT
(
21
)
,
.
SATA_MAX_WAKE
(
7
)
,
...
...
@@ -631,8 +663,8 @@ gtx(
.
DRPRDY
()
,
.
DRPWE
(
1'b0
)
,
.
GTREFCLKMONITOR
()
,
.
QPLLCLK
(
/*gtrefclk*/
)
,
.
QPLLREFCLK
(
/*gtrefclk*/
)
,
.
QPLLCLK
(
1'b0
/*gtrefclk*/
)
,
.
QPLLREFCLK
(
1'b0
/*gtrefclk*/
)
,
.
RXSYSCLKSEL
(
2'b00
)
,
.
TXSYSCLKSEL
(
2'b00
)
,
.
DMONITOROUT
()
,
...
...
@@ -657,8 +689,8 @@ gtx(
.
RXCDRRESETRSV
(
1'b0
)
,
.
RXCLKCORCNT
()
,
.
RX8B10BEN
(
1'b0
)
,
.
RXUSRCLK
(
rxusr
clk
)
,
.
RXUSRCLK2
(
rxusr
clk
)
,
.
RXUSRCLK
(
x
clk
)
,
.
RXUSRCLK2
(
x
clk
)
,
.
RXDATA
(
rxdata_gtx
)
,
.
RXPRBSERR
()
,
.
RXPRBSSEL
(
3'd0
)
,
...
...
@@ -729,7 +761,7 @@ gtx(
.
RXOSHOLD
(
1'b0
)
,
.
RXOSOVRDEN
(
1'b0
)
,
.
RXRATEDONE
()
,
.
RXOUTCLK
(
xclk
)
,
.
RXOUTCLK
(
xclk
_gtx
)
,
.
RXOUTCLKFABRIC
()
,
.
RXOUTCLKPCS
()
,
.
RXOUTCLKSEL
(
3'b010
)
,
...
...
@@ -806,7 +838,7 @@ gtx(
.
TXDATA
(
txdata_gtx
)
,
.
GTXTXN
(
txn
)
,
.
GTXTXP
(
txp
)
,
.
TXOUTCLK
(
txoutclk
)
,
.
TXOUTCLK
(
txoutclk
_gtx
)
,
.
TXOUTCLKFABRIC
()
,
.
TXOUTCLKPCS
()
,
.
TXOUTCLKSEL
(
3'b010
)
,
...
...
host/link.v
View file @
b2f9de10
...
...
@@ -99,7 +99,20 @@ module link #(
// to phy
output
wire
[
DATA_BYTE_WIDTH
*
8
-
1
:
0
]
phy_data_out
,
output
wire
[
DATA_BYTE_WIDTH
-
1
:
0
]
phy_isk_out
// charisk
)
;
// latching data-primitives stream from phy
reg
[
DATA_BYTE_WIDTH
*
8
-
1
:
0
]
phy_data_in_r
;
reg
[
DATA_BYTE_WIDTH
-
1
:
0
]
phy_isk_in_r
;
// charisk
reg
[
DATA_BYTE_WIDTH
-
1
:
0
]
phy_err_in_r
;
// disperr | notintable
always
@
(
posedge
clk
)
begin
phy_data_in_r
<=
phy_data_in
;
phy_isk_in_r
<=
phy_isk_in
;
phy_err_in_r
<=
phy_err_in
;
end
wire
frame_done
;
// scrambled data
wire
[
DATA_BYTE_WIDTH
*
8
-
1
:
0
]
scrambler_out
;
...
...
@@ -494,7 +507,7 @@ scrambler scrambler(
.
val_in
(
select_prim
[
CODE_DATA
]
|
inc_is_data
)
,
.
data_in
(
crc_dword
&
{
DATA_BYTE_WIDTH
*
8
{
select_prim
[
CODE_CRC
]
}}
|
data_in
&
{
DATA_BYTE_WIDTH
*
8
{
select_prim
[
CODE_DATA
]
}}
|
phy_data_in
&
{
DATA_BYTE_WIDTH
*
8
{
inc_is_data
}}
)
,
phy_data_in
_r
&
{
DATA_BYTE_WIDTH
*
8
{
inc_is_data
}}
)
,
.
data_out
(
scrambler_out
)
)
;
...
...
@@ -557,24 +570,24 @@ assign incom_invalidate = state_rcvr_eof & crc_bad & ~alignes_pair | state_rcvr
// shows that incoming primitive or data is ready to be processed // TODO somehow move alignes_pair into dword_val
assign
dword_val
=
|
rcvd_dword
&
phy_ready
&
~
rcvd_dword
[
CODE_ALIGNP
]
;
// determine imcoming primitive type
assign
rcvd_dword
[
CODE_DATA
]
=
~|
phy_isk_in
;
assign
rcvd_dword
[
CODE_DATA
]
=
~|
phy_isk_in
_r
;
assign
rcvd_dword
[
CODE_CRC
]
=
1'b0
;
assign
rcvd_dword
[
CODE_SYNCP
]
=
phy_isk_in
[
0
]
==
1'b1
&
~|
phy_isk_in
[
DATA_BYTE_WIDTH
-
1
:
1
]
&
prim_data
[
CODE_SYNCP
]
==
phy_data_in
;
assign
rcvd_dword
[
CODE_ALIGNP
]
=
phy_isk_in
[
0
]
==
1'b1
&
~|
phy_isk_in
[
DATA_BYTE_WIDTH
-
1
:
1
]
&
prim_data
[
CODE_ALIGNP
]
==
phy_data_in
;
assign
rcvd_dword
[
CODE_XRDYP
]
=
phy_isk_in
[
0
]
==
1'b1
&
~|
phy_isk_in
[
DATA_BYTE_WIDTH
-
1
:
1
]
&
prim_data
[
CODE_XRDYP
]
==
phy_data_in
;
assign
rcvd_dword
[
CODE_SOFP
]
=
phy_isk_in
[
0
]
==
1'b1
&
~|
phy_isk_in
[
DATA_BYTE_WIDTH
-
1
:
1
]
&
prim_data
[
CODE_SOFP
]
==
phy_data_in
;
assign
rcvd_dword
[
CODE_HOLDAP
]
=
phy_isk_in
[
0
]
==
1'b1
&
~|
phy_isk_in
[
DATA_BYTE_WIDTH
-
1
:
1
]
&
prim_data
[
CODE_HOLDAP
]
==
phy_data_in
;
assign
rcvd_dword
[
CODE_HOLDP
]
=
phy_isk_in
[
0
]
==
1'b1
&
~|
phy_isk_in
[
DATA_BYTE_WIDTH
-
1
:
1
]
&
prim_data
[
CODE_HOLDP
]
==
phy_data_in
;
assign
rcvd_dword
[
CODE_EOFP
]
=
phy_isk_in
[
0
]
==
1'b1
&
~|
phy_isk_in
[
DATA_BYTE_WIDTH
-
1
:
1
]
&
prim_data
[
CODE_EOFP
]
==
phy_data_in
;
assign
rcvd_dword
[
CODE_WTRMP
]
=
phy_isk_in
[
0
]
==
1'b1
&
~|
phy_isk_in
[
DATA_BYTE_WIDTH
-
1
:
1
]
&
prim_data
[
CODE_WTRMP
]
==
phy_data_in
;
assign
rcvd_dword
[
CODE_RRDYP
]
=
phy_isk_in
[
0
]
==
1'b1
&
~|
phy_isk_in
[
DATA_BYTE_WIDTH
-
1
:
1
]
&
prim_data
[
CODE_RRDYP
]
==
phy_data_in
;
assign
rcvd_dword
[
CODE_IPP
]
=
phy_isk_in
[
0
]
==
1'b1
&
~|
phy_isk_in
[
DATA_BYTE_WIDTH
-
1
:
1
]
&
prim_data
[
CODE_IPP
]
==
phy_data_in
;
assign
rcvd_dword
[
CODE_DMATP
]
=
phy_isk_in
[
0
]
==
1'b1
&
~|
phy_isk_in
[
DATA_BYTE_WIDTH
-
1
:
1
]
&
prim_data
[
CODE_DMATP
]
==
phy_data_in
;
assign
rcvd_dword
[
CODE_OKP
]
=
phy_isk_in
[
0
]
==
1'b1
&
~|
phy_isk_in
[
DATA_BYTE_WIDTH
-
1
:
1
]
&
prim_data
[
CODE_OKP
]
==
phy_data_in
;
assign
rcvd_dword
[
CODE_ERRP
]
=
phy_isk_in
[
0
]
==
1'b1
&
~|
phy_isk_in
[
DATA_BYTE_WIDTH
-
1
:
1
]
&
prim_data
[
CODE_ERRP
]
==
phy_data_in
;
assign
rcvd_dword
[
CODE_SYNCP
]
=
phy_isk_in
_r
[
0
]
==
1'b1
&
~|
phy_isk_in_r
[
DATA_BYTE_WIDTH
-
1
:
1
]
&
prim_data
[
CODE_SYNCP
]
==
phy_data_in_r
;
assign
rcvd_dword
[
CODE_ALIGNP
]
=
phy_isk_in
_r
[
0
]
==
1'b1
&
~|
phy_isk_in_r
[
DATA_BYTE_WIDTH
-
1
:
1
]
&
prim_data
[
CODE_ALIGNP
]
==
phy_data_in_r
;
assign
rcvd_dword
[
CODE_XRDYP
]
=
phy_isk_in
_r
[
0
]
==
1'b1
&
~|
phy_isk_in_r
[
DATA_BYTE_WIDTH
-
1
:
1
]
&
prim_data
[
CODE_XRDYP
]
==
phy_data_in_r
;
assign
rcvd_dword
[
CODE_SOFP
]
=
phy_isk_in
_r
[
0
]
==
1'b1
&
~|
phy_isk_in_r
[
DATA_BYTE_WIDTH
-
1
:
1
]
&
prim_data
[
CODE_SOFP
]
==
phy_data_in_r
;
assign
rcvd_dword
[
CODE_HOLDAP
]
=
phy_isk_in
_r
[
0
]
==
1'b1
&
~|
phy_isk_in_r
[
DATA_BYTE_WIDTH
-
1
:
1
]
&
prim_data
[
CODE_HOLDAP
]
==
phy_data_in_r
;
assign
rcvd_dword
[
CODE_HOLDP
]
=
phy_isk_in
_r
[
0
]
==
1'b1
&
~|
phy_isk_in_r
[
DATA_BYTE_WIDTH
-
1
:
1
]
&
prim_data
[
CODE_HOLDP
]
==
phy_data_in_r
;
assign
rcvd_dword
[
CODE_EOFP
]
=
phy_isk_in
_r
[
0
]
==
1'b1
&
~|
phy_isk_in_r
[
DATA_BYTE_WIDTH
-
1
:
1
]
&
prim_data
[
CODE_EOFP
]
==
phy_data_in_r
;
assign
rcvd_dword
[
CODE_WTRMP
]
=
phy_isk_in
_r
[
0
]
==
1'b1
&
~|
phy_isk_in_r
[
DATA_BYTE_WIDTH
-
1
:
1
]
&
prim_data
[
CODE_WTRMP
]
==
phy_data_in_r
;
assign
rcvd_dword
[
CODE_RRDYP
]
=
phy_isk_in
_r
[
0
]
==
1'b1
&
~|
phy_isk_in_r
[
DATA_BYTE_WIDTH
-
1
:
1
]
&
prim_data
[
CODE_RRDYP
]
==
phy_data_in_r
;
assign
rcvd_dword
[
CODE_IPP
]
=
phy_isk_in
_r
[
0
]
==
1'b1
&
~|
phy_isk_in_r
[
DATA_BYTE_WIDTH
-
1
:
1
]
&
prim_data
[
CODE_IPP
]
==
phy_data_in_r
;
assign
rcvd_dword
[
CODE_DMATP
]
=
phy_isk_in
_r
[
0
]
==
1'b1
&
~|
phy_isk_in_r
[
DATA_BYTE_WIDTH
-
1
:
1
]
&
prim_data
[
CODE_DMATP
]
==
phy_data_in_r
;
assign
rcvd_dword
[
CODE_OKP
]
=
phy_isk_in
_r
[
0
]
==
1'b1
&
~|
phy_isk_in_r
[
DATA_BYTE_WIDTH
-
1
:
1
]
&
prim_data
[
CODE_OKP
]
==
phy_data_in_r
;
assign
rcvd_dword
[
CODE_ERRP
]
=
phy_isk_in
_r
[
0
]
==
1'b1
&
~|
phy_isk_in_r
[
DATA_BYTE_WIDTH
-
1
:
1
]
&
prim_data
[
CODE_ERRP
]
==
phy_data_in_r
;
// phy level errors handling TODO
assign
dec_err
=
|
phy_err_in
;
assign
dec_err
=
|
phy_err_in
_r
;
// form a response to transport layer
assign
frame_done
=
frame_done_good
|
frame_done_bad
;
...
...
@@ -586,7 +599,7 @@ assign frame_done_bad = state_wait & dword_val & rcvd_dword[CODE_ERRP];
always
@
(
posedge
clk
)
if
(
~|
rcvd_dword
&
phy_ready
)
begin
$
display
(
"%m: invalid primitive recieved : %h, conrol : %h, err : %h"
,
phy_data_in
,
phy_isk_in
,
phy_err_in
)
;
$
display
(
"%m: invalid primitive recieved : %h, conrol : %h, err : %h"
,
phy_data_in
_r
,
phy_isk_in_r
,
phy_err_in_r
)
;
$
finish
;
end
// States checker
...
...
@@ -663,4 +676,9 @@ end
`endif
`ifdef
LA
`endif
endmodule
host/sata_phy.v
View file @
b2f9de10
...
...
@@ -184,9 +184,26 @@ always @ (posedge gtrefclk)
*/
wire
usrpll_locked
;
// make tx/rxreset synchronous to gtrefclk - gather singals from different domains: async, aclk, usrclk2, gtrefclk
reg
rxreset_f
;
reg
txreset_f
;
reg
rxreset_f_r
;
reg
txreset_f_r
;
reg
rxreset_f_rr
;
reg
txreset_f_rr
;
always
@
(
posedge
gtrefclk
)
begin
rxreset_f
<=
~
cplllock
|
cpllreset
|
rxreset_oob
&
gtx_configured
;
txreset_f
<=
~
cplllock
|
cpllreset
;
txreset_f_r
<=
txreset_f
;
rxreset_f_r
<=
rxreset_f
;
txreset_f_rr
<=
txreset_f_r
;
rxreset_f_rr
<=
rxreset_f_r
;
end
assign
rxreset
=
rxreset_f_rr
;
assign
txreset
=
txreset_f_rr
;
assign
cpllreset
=
extrst
;
assign
rxreset
=
~
cplllock
|
cpllreset
|
rxreset_oob
&
gtx_configured
;
assign
txreset
=
~
cplllock
|
cpllreset
;
assign
rxuserrdy
=
usrpll_locked
&
cplllock
&
~
cpllreset
&
~
rxreset
&
rxeyereset_done
&
sata_reset_done
;
assign
txuserrdy
=
usrpll_locked
&
cplllock
&
~
cpllreset
&
~
txreset
&
txpmareset_done
&
sata_reset_done
;
...
...
synt/top_timing.xdc
View file @
b2f9de10
# clock, received via FCLK input from PS7
# barely used for now
create_clock -name axi_aclk0 -period 20.000 -waveform {0.000 10.000}
{get_nets axi_aclk0}
create_clock -name axi_aclk0 -period 20.000 -waveform {0.000 10.000}
[get_nets axi_aclk0]
# external clock 150Mhz
create_clock -name gtrefclk -period 6.666 -waveform {0.000 3.333}
{get_nets sata_top.sata_host.sata_phy.gtrefclk}
create_clock -name gtrefclk -period 6.666 -waveform {0.000 3.333}
[get_nets sata_top/sata_host/phy/gtrefclk]
# after plls inside of GTX:
create_clock -name txoutclk -period
13.333 -waveform {0.000 6.666} {get_nets sata_top.sata_host.sata_phy.txoutclk}
create_clock -name txoutclk -period
6.666 -waveform {0.000 3.333} [get_nets sata_top/sata_host/phy/txoutclk]
# txoutclk -> userpll, which gives us 2 clocks: userclk and userclk2. The second one is sata host clk
create_generate_clock -name usrclk -source [get_clocks txoutclk] -multiply_by 2 [get_nets sata_top.sata_host.sata_phy.usrclk]
create_generate_clock -name sclk -source [get_clocks txoutclk] [get_nets sata_top.sata_host.sata_phy.usrclk2]
# recovered sata parallel clock
create_clock -name xclk -period 6.666 -waveform {0.000 3.333} [get_nets sata_top/sata_host/phy/gtx_wrap/xclk]
# txoutclk -> userpll, which gives us 2 clocks: userclk and userclk2. The second one is sata host clk
create_generated_clock -name usrclk [get_nets sata_top/sata_host/phy/CLK]
create_generated_clock -name sclk [get_nets sata_top/sata_host/phy/clk]
tb/test_top.v
View file @
b2f9de10
...
...
@@ -187,6 +187,9 @@ begin
/* for (i = 0; i < 32; i = i + 1) begin
$display("data received : %h", dev.receive_data[i]);
end*/
RST
=
1'b1
;
repeat
(
2000
)
@
(
posedge
EXTCLK_P
)
;
$
display
(
"============= DONE ============="
)
;
$
finish
;
...
...
@@ -240,7 +243,7 @@ begin
end
*/
initial
begin
#
15
0000
;
#
20
0000
;
$
display
(
"[Test] Failed"
)
;
$
display
(
"============= TIMELIMIT ============="
)
;
$
finish
;
...
...
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