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
87fd75fd
Commit
87fd75fd
authored
Dec 10, 2016
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fixed 2 more bugs in h2d/fifo control
parent
282f41b3
Changes
13
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
303 additions
and
97 deletions
+303
-97
ahci_fis_receive.v
ahci/ahci_fis_receive.v
+1
-1
ahci_sata_layers.v
ahci/ahci_sata_layers.v
+34
-4
ahci_top.v
ahci/ahci_top.v
+103
-7
sata_ahci_top.v
ahci/sata_ahci_top.v
+8
-1
sata_device.v
device/sata_device.v
+6
-1
link.v
host/link.v
+10
-0
ahci_defaults.vh
includes/ahci_defaults.vh
+1
-1
ahci_localparams.vh
includes/ahci_localparams.vh
+1
-1
create_ahci_registers.py
py393sata/create_ahci_registers.py
+1
-1
x393sata.py
py393sata/x393sata.py
+13
-1
tb_ahci.tf
tb/tb_ahci.tf
+5
-0
tb_ahci_01.sav
tb_ahci_01.sav
+120
-79
x393_sata.bit
x393_sata.bit
+0
-0
No files found.
ahci/ahci_fis_receive.v
View file @
87fd75fd
...
@@ -393,7 +393,7 @@ localparam DATA_TYPE_ERR = 3;
...
@@ -393,7 +393,7 @@ localparam DATA_TYPE_ERR = 3;
if
(
reg_sdb
[
1
])
sactive0
<=
hba_data_in
[
0
]
;
if
(
reg_sdb
[
1
])
sactive0
<=
hba_data_in
[
0
]
;
if
(
hba_rst
||
reg_sdb
[
0
]
||
clear_xfer_cntr
)
xfer_cntr_r
[
31
:
2
]
<=
0
;
if
(
hba_rst
||
reg_sdb
[
0
]
||
clear_xfer_cntr
)
xfer_cntr_r
[
31
:
2
]
<=
0
;
else
if
(
reg_ps
[
4
]
||
reg_ds
[
5
])
xfer_cntr_r
[
31
:
2
]
<=
{
reg_ds
[
5
]
?
hba_data_in
[
31
:
16
]
:
16'b0
,
else
if
(
reg_ps
[
4
]
||
reg_ds
[
5
])
xfer_cntr_r
[
31
:
2
]
<=
{
reg_ds
[
5
]
?
hba_data_in
[
31
:
16
]
:
16'b0
,
hba_data_in
[
15
:
2
]
}
+
hba_data_in
[
1
]
;
// round up
hba_data_in
[
15
:
2
]
}
+
hba_data_in
[
1
]
;
// round up
else
if
((
decr_dwcw
||
decr_dwcr
)
&&
!
xfer_cntr_zero_r
)
xfer_cntr_r
[
31
:
2
]
<=
{
xfer_cntr_r
[
31
:
2
]
}
-
else
if
((
decr_dwcw
||
decr_dwcr
)
&&
!
xfer_cntr_zero_r
)
xfer_cntr_r
[
31
:
2
]
<=
{
xfer_cntr_r
[
31
:
2
]
}
-
...
...
ahci/ahci_sata_layers.v
View file @
87fd75fd
...
@@ -24,7 +24,12 @@
...
@@ -24,7 +24,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/> .
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*/
*/
`timescale
1
ns
/
1
ps
`timescale
1
ns
/
1
ps
//`define CHECK_LOW_H2D_FIFO // reduce actual h2d fifo size during simulation, to test h2d_ready
/** TODO:
1. Check nothing is left in H2D FIFO after data is sent - it will happen after DPATp received.
2. Make DPATp an error? It is not easy to insert 0x00000046" data FIS header before remaining data (already in FIS)
- it may also hold fis_transmit, as maximal data fis is 4x of the FIFO size.
*/
module
ahci_sata_layers
#(
module
ahci_sata_layers
#(
`ifdef
USE_DATASCOPE
`ifdef
USE_DATASCOPE
parameter
ADDRESS_BITS
=
10
,
//for datascope
parameter
ADDRESS_BITS
=
10
,
//for datascope
...
@@ -105,6 +110,9 @@ module ahci_sata_layers #(
...
@@ -105,6 +110,9 @@ module ahci_sata_layers #(
output
wire
txn_out
,
output
wire
txn_out
,
input
wire
rxp_in
,
input
wire
rxp_in
,
input
wire
rxn_in
,
input
wire
rxn_in
,
output
debug_is_data
,
// @clk (sata clk) - last symbol was data output
output
debug_dmatp
,
// @clk (sata clk) - received CODE_DMATP
`ifdef
USE_DATASCOPE
`ifdef
USE_DATASCOPE
// Datascope interface (write to memory that can be software-read)
// Datascope interface (write to memory that can be software-read)
output
datascope_clk
,
output
datascope_clk
,
...
@@ -142,6 +150,13 @@ module ahci_sata_layers #(
...
@@ -142,6 +150,13 @@ module ahci_sata_layers #(
localparam
H2D_TYPE_FIS_HEAD
=
1
;
localparam
H2D_TYPE_FIS_HEAD
=
1
;
localparam
H2D_TYPE_FIS_LAST
=
2
;
localparam
H2D_TYPE_FIS_LAST
=
2
;
`ifdef
SIMULATION
`ifdef
CHECK_LOW_H2D_FIFO
localparam
H2D_FIFO_THRESHOLD
=
4
;
// to test h2d_ready - will turn off frequently, much earlier than fifo almost full
`endif
`endif
wire
phy_ready
;
// active when GTX gets aligned output
wire
phy_ready
;
// active when GTX gets aligned output
wire
link_established
;
// Received 3 back-to-back non-ALIGNp
wire
link_established
;
// Received 3 back-to-back non-ALIGNp
wire
[
31
:
0
]
ll_h2d_data_in
;
wire
[
31
:
0
]
ll_h2d_data_in
;
...
@@ -186,7 +201,9 @@ module ahci_sata_layers #(
...
@@ -186,7 +201,9 @@ module ahci_sata_layers #(
wire
[
FIFO_ADDR_WIDTH
:
0
]
d2h_fill
;
wire
[
FIFO_ADDR_WIDTH
:
0
]
d2h_fill
;
wire
d2h_nempty
;
wire
d2h_nempty
;
wire
h2d_fifo_rd
=
h2d_nempty
&&
ll_strobe_out
;
// TODO: check latency in link.v
wire
h2d_fifo_rd
=
h2d_nempty
&&
ll_strobe_out
;
// TODO: check latency in link.v
wire
h2d_fifo_wr
=
h2d_valid
;
// wire h2d_fifo_wr = h2d_valid;
//2016.12.10
wire
h2d_fifo_wr
=
h2d_valid
&&
h2d_ready
;
// or should valid depend on ready in the fis_transmit?
wire
d2h_fifo_rd
=
d2h_valid
&&
d2h_ready
;
wire
d2h_fifo_rd
=
d2h_valid
&&
d2h_ready
;
wire
d2h_fifo_wr
=
ll_d2h_valid
||
fis_over_r
;
// fis_over_r will push FIS end to FIFO
wire
d2h_fifo_wr
=
ll_d2h_valid
||
fis_over_r
;
// fis_over_r will push FIS end to FIFO
...
@@ -205,7 +222,18 @@ assign ll_h2d_last = (h2d_type_out == H2D_TYPE_FIS_LAST);
...
@@ -205,7 +222,18 @@ assign ll_h2d_last = (h2d_type_out == H2D_TYPE_FIS_LAST);
assign
d2h_valid
=
d2h_nempty
;
assign
d2h_valid
=
d2h_nempty
;
assign
d2h_many
=
|
d2h_fill
[
FIFO_ADDR_WIDTH
:
3
]
;
//
assign
d2h_many
=
|
d2h_fill
[
FIFO_ADDR_WIDTH
:
3
]
;
//
assign
h2d_ready
=
!
h2d_fill
[
FIFO_ADDR_WIDTH
]
&&
!
(
&
h2d_fill
[
FIFO_ADDR_WIDTH
:
3
])
;
// assign h2d_ready = !h2d_fill[FIFO_ADDR_WIDTH] && !(&h2d_fill[FIFO_ADDR_WIDTH:3]);
// 2016:12:10 sometimes overflow happened because of a BUG
`ifdef
SIMULATION
`ifdef
CHECK_LOW_H2D_FIFO
assign
h2d_ready
=
!
h2d_fill
[
FIFO_ADDR_WIDTH
]
&&
(
h2d_fill
<
((
1
<<
BITS_TO_START_XMIT
)
+
H2D_FIFO_THRESHOLD
))
;
`else
assign
h2d_ready
=
!
h2d_fill
[
FIFO_ADDR_WIDTH
]
&&
!
(
&
h2d_fill
[
FIFO_ADDR_WIDTH
-
1
:
3
])
;
// same as with synthesis
`endif
`else
assign
h2d_ready
=
!
h2d_fill
[
FIFO_ADDR_WIDTH
]
&&
!
(
&
h2d_fill
[
FIFO_ADDR_WIDTH
-
1
:
3
])
;
`endif
assign
ll_d2h_almost_full
=
d2h_fill
[
FIFO_ADDR_WIDTH
]
||
&
d2h_fill
[
FIFO_ADDR_WIDTH
-
1
:
6
]
;
// 63 dwords (maybe use :5?) - time to tell device to stop
assign
ll_d2h_almost_full
=
d2h_fill
[
FIFO_ADDR_WIDTH
]
||
&
d2h_fill
[
FIFO_ADDR_WIDTH
-
1
:
6
]
;
// 63 dwords (maybe use :5?) - time to tell device to stop
// assign ll_frame_req_w = !ll_frame_busy && h2d_pending && (((h2d_type == H2D_TYPE_FIS_LAST) && h2d_fifo_wr ) || (|h2d_fill[FIFO_ADDR_WIDTH : BITS_TO_START_XMIT]));
// assign ll_frame_req_w = !ll_frame_busy && h2d_pending && (((h2d_type == H2D_TYPE_FIS_LAST) && h2d_fifo_wr ) || (|h2d_fill[FIFO_ADDR_WIDTH : BITS_TO_START_XMIT]));
...
@@ -317,7 +345,9 @@ assign debug_phy = debug_phy0;
...
@@ -317,7 +345,9 @@ assign debug_phy = debug_phy0;
.
phy_err_in
(
ph2ll_err_out
)
,
// input[3:0] wire // disperr | notintable
.
phy_err_in
(
ph2ll_err_out
)
,
// input[3:0] wire // disperr | notintable
// to phy
// to phy
.
phy_data_out
(
ll2ph_data_in
)
,
// output[31:0] wire
.
phy_data_out
(
ll2ph_data_in
)
,
// output[31:0] wire
.
phy_isk_out
(
ll2ph_charisk_in
)
,
// output[3:0] wire // charisk
.
phy_isk_out
(
ll2ph_charisk_in
)
,
// output[3:0] wire // charisk
.
debug_is_data
(
debug_is_data
)
,
// output reg @clk (sata clk) - last symbol was data output
.
debug_dmatp
(
debug_dmatp
)
,
// output reg @clk (sata clk) - received CODE_DMATP
.
debug_out
(
debug_link
)
.
debug_out
(
debug_link
)
)
;
)
;
...
...
ahci/ahci_top.v
View file @
87fd75fd
...
@@ -190,6 +190,8 @@ module ahci_top#(
...
@@ -190,6 +190,8 @@ module ahci_top#(
output
irq
,
// CPU interrupt request
output
irq
,
// CPU interrupt request
input
debug_link_send_data
,
// @posedge sata_clk - last symbol was data output (to count sent out)
input
debug_link_dmatp
,
// link received DMATp from device
`ifdef
USE_DATASCOPE
`ifdef
USE_DATASCOPE
// Datascope interface (write to memory that can be software-read)
// Datascope interface (write to memory that can be software-read)
...
@@ -1204,6 +1206,7 @@ wire [9:0] xmit_dbg_01;
...
@@ -1204,6 +1206,7 @@ wire [9:0] xmit_dbg_01;
.
soft_write_addr
(
soft_write_addr
)
,
// input[9:0]
.
soft_write_addr
(
soft_write_addr
)
,
// input[9:0]
.
soft_write_data
(
soft_write_data
)
,
// input[31:0]
.
soft_write_data
(
soft_write_data
)
,
// input[31:0]
.
soft_write_en
(
soft_write_en
)
,
// input
.
soft_write_en
(
soft_write_en
)
,
// input
.
cfis
(
fsnd_cfis_xmit
)
,
// input command FIS - to reset dword counter
.
h2d_data
(
h2d_data
)
,
// input[31:0]
.
h2d_data
(
h2d_data
)
,
// input[31:0]
.
h2d_type
(
h2d_type
)
,
// input[1:0]
.
h2d_type
(
h2d_type
)
,
// input[1:0]
.
h2d_valid
(
h2d_valid
)
,
// input
.
h2d_valid
(
h2d_valid
)
,
// input
...
@@ -1212,6 +1215,8 @@ wire [9:0] xmit_dbg_01;
...
@@ -1212,6 +1215,8 @@ wire [9:0] xmit_dbg_01;
.
d2h_type
(
d2h_type
)
,
// input[1:0]
.
d2h_type
(
d2h_type
)
,
// input[1:0]
.
d2h_valid
(
d2h_valid
)
,
// input
.
d2h_valid
(
d2h_valid
)
,
// input
.
d2h_ready
(
d2h_ready
)
,
// input
.
d2h_ready
(
d2h_ready
)
,
// input
.
debug_link_send_data
(
debug_link_send_data
)
,
// input
.
debug_link_dmatp
(
debug_link_dmatp
)
,
// link received DMATp from device
.
datascope_clk
(
datascope_clk
)
,
// output
.
datascope_clk
(
datascope_clk
)
,
// output
.
datascope_waddr
(
datascope_waddr
)
,
// output[9:0] reg
.
datascope_waddr
(
datascope_waddr
)
,
// output[9:0] reg
.
datascope_we
(
datascope_we
)
,
// output
.
datascope_we
(
datascope_we
)
,
// output
...
@@ -1327,6 +1332,8 @@ module datascope_timing #(
...
@@ -1327,6 +1332,8 @@ module datascope_timing #(
input
[
31
:
0
]
soft_write_data
,
input
[
31
:
0
]
soft_write_data
,
input
soft_write_en
,
input
soft_write_en
,
input
cfis
,
// to reset send counter
// outgoing FISes
// outgoing FISes
input
[
31
:
0
]
h2d_data
,
// 32-bit data from the system memory to HBA (dma data)
input
[
31
:
0
]
h2d_data
,
// 32-bit data from the system memory to HBA (dma data)
input
[
1
:
0
]
h2d_type
,
// 0 - data, 1 - FIS head, 2 - FIS END (make FIS_Last?)
input
[
1
:
0
]
h2d_type
,
// 0 - data, 1 - FIS head, 2 - FIS END (make FIS_Last?)
...
@@ -1341,6 +1348,8 @@ module datascope_timing #(
...
@@ -1341,6 +1348,8 @@ module datascope_timing #(
input
d2h_valid
,
// Data available from the transport layer in FIFO
input
d2h_valid
,
// Data available from the transport layer in FIFO
input
d2h_ready
,
// This module or DMA consumes DWORD
input
d2h_ready
,
// This module or DMA consumes DWORD
input
debug_link_send_data
,
// @posedge mclk (sata_clk, 75MHz) - last symbol was data output (to count sent out)
input
debug_link_dmatp
,
// link received DMATp from device
output
datascope_clk
,
output
datascope_clk
,
output
reg
[
ADDRESS_BITS
-
1
:
0
]
datascope_waddr
,
output
reg
[
ADDRESS_BITS
-
1
:
0
]
datascope_waddr
,
output
datascope_we
,
output
datascope_we
,
...
@@ -1360,6 +1369,9 @@ module datascope_timing #(
...
@@ -1360,6 +1369,9 @@ module datascope_timing #(
reg
[
31
:
0
]
fis_data
;
reg
[
31
:
0
]
fis_data
;
reg
[
27
:
0
]
cur_time
;
reg
[
27
:
0
]
cur_time
;
reg
was_h2d_last
;
reg
was_h2d_last
;
reg
h2d_ready_d
;
// delayed h2d_ready to count 1->0 transitions
reg
[
7
:
0
]
h2d_nready_cntr
;
// count (infrequent) events when h2d FIFO turns off ready
// reg
wire
fis_start
=
(
h2d_valid
&&
h2d_ready
&&
(
h2d_type
==
1
))
||
wire
fis_start
=
(
h2d_valid
&&
h2d_ready
&&
(
h2d_type
==
1
))
||
(
d2h_valid
&&
d2h_ready
&&
(
d2h_type
==
1
))
;
(
d2h_valid
&&
d2h_ready
&&
(
d2h_type
==
1
))
;
...
@@ -1367,11 +1379,44 @@ module datascope_timing #(
...
@@ -1367,11 +1379,44 @@ module datascope_timing #(
// wire fis_end_we = (fis_left == 0) || fis_end;
// wire fis_end_we = (fis_left == 0) || fis_end;
wire
pre_we_w
=
fis_run
&&
(
d2h_valid
?
(
d2h_valid
&&
d2h_ready
)
:
(
h2d_valid
&&
h2d_ready
))
;
wire
pre_we_w
=
fis_run
&&
(
d2h_valid
?
(
d2h_valid
&&
d2h_ready
)
:
(
h2d_valid
&&
h2d_ready
))
;
reg
fis_run_d2
;
reg
fis_run_d3
;
reg
fis_run_d4
;
// to read non 0x39 d2h fis
reg
fis_run_d5
;
// number of dwords sent by link a s data symbols
// reg fis_first;
reg
data_fis
;
reg
pre_we_r
;
reg
pre_we_r
;
reg
we_r
;
reg
we_r
;
wire
inc_dw_cntr
=
fis_run
&&
(
d2h_valid
?
(
d2h_ready
&&
(
d2h_type
==
0
))
:
(
h2d_valid
&&
h2d_ready
))
;
wire
is_cfis_w
=
h2d_valid
&&
(
h2d_data
[
7
:
0
]
==
8'h27
)
&&
// valid @ fis_start
((
h2d_data
[
23
:
16
]
==
8'h25
)
||
// Read DMA Extended
(
h2d_data
[
23
:
16
]
==
8'h35
)
||
// Write DMA Extended
(
h2d_data
[
23
:
16
]
==
8'hC8
)
||
// Read DMA
(
h2d_data
[
23
:
16
]
==
8'hCA
))
;
// Write DMA
reg
is_cfis_r
;
reg
[
23
:
0
]
last_dma_cmd
;
reg
set_dma_count
;
reg
[
21
:
0
]
dw_count
;
wire
[
7
:
0
]
fis_data_w
=
d2h_valid
?
d2h_data
[
7
:
0
]
:
h2d_data
[
7
:
0
]
;
reg
[
31
:
0
]
non_dma_act
;
// last D2H FIS that was not DMA activate, received after DMA/IO command
reg
set_non_dma_act
;
reg
[
21
:
0
]
link_count
;
reg
[
21
:
0
]
link_count_latched
;
reg
reset_link_count
;
// data FIS from dma command until
reg
was_link_dmatp
;
//
// input debug_link_dmatp, // link received DMATp from device
assign
datascope_we
=
we_r
;
assign
datascope_we
=
we_r
;
assign
datascope_clk
=
clk
;
assign
datascope_clk
=
clk
;
always
@
(
posedge
clk
)
begin
always
@
(
posedge
clk
)
begin
was_h2d_last
<=
h2d_type
[
1
]
&&
h2d_valid
&&
h2d_ready
;
was_h2d_last
<=
h2d_type
[
1
]
&&
h2d_valid
&&
h2d_ready
;
...
@@ -1384,17 +1429,29 @@ module datascope_timing #(
...
@@ -1384,17 +1429,29 @@ module datascope_timing #(
else
if
(
write_tag_w
)
pend_punch_time
<=
1
;
else
if
(
write_tag_w
)
pend_punch_time
<=
1
;
else
if
(
write_punch_time
)
pend_punch_time
<=
0
;
else
if
(
write_punch_time
)
pend_punch_time
<=
0
;
if
(
write_punch_time
||
fis_start
)
datascope_di
<=
{
write_punch_time
?{
1'b1
,
punch_tag
}:{
3'b0
,
d2h_valid
},
cur_time
};
if
(
write_punch_time
||
fis_start
)
datascope_di
<=
{
write_punch_time
?{
1'b1
,
punch_tag
}:{
3'b0
,
d2h_valid
},
cur_time
};
else
if
(
fis_we
)
datascope_di
<=
fis_data
;
else
if
(
fis_we
)
datascope_di
<=
fis_data
;
else
if
(
!
fis_run
&&
fis_run_d
)
datascope_di
<=
{
19'h7fff8
,
fis_len
};
else
if
(
!
fis_run
&&
fis_run_d
)
datascope_di
<=
{
19'h7fff8
,
fis_len
};
else
if
(
!
fis_run_d
&&
fis_run_d2
)
datascope_di
<=
{
10'h2a8
,
dw_count
};
else
if
(
!
fis_run_d2
&&
fis_run_d3
)
datascope_di
<=
{
8'h55
,
last_dma_cmd
};
else
if
(
!
fis_run_d3
&&
fis_run_d4
)
datascope_di
<=
non_dma_act
;
else
if
(
!
fis_run_d4
&&
fis_run_d5
)
datascope_di
<=
{
h2d_nready_cntr
[
7
:
0
]
,
was_link_dmatp
,
1'b0
,
link_count_latched
};
pre_we_r
<=
pre_we_w
||
fis_start
;
pre_we_r
<=
pre_we_w
||
fis_start
;
we_r
<=
write_punch_time
||
fis_start
||
(
fis_we
?
pre_we_r
:
(
!
fis_run
&&
fis_run_d
))
;
// we_r <= write_punch_time || fis_start || (fis_we ? pre_we_r : (!fis_run && fis_run_d));
we_r
<=
write_punch_time
||
fis_start
||
(
fis_we
?
pre_we_r
:
(
!
fis_run
&&
(
fis_run_d
||
fis_run_d2
||
fis_run_d3
||
fis_run_d4
||
fis_run_d5
)))
;
// 3 after
if
(
fis_start
)
fis_left
<=
FIS_LEN
-
1
;
if
(
fis_start
)
fis_left
<=
FIS_LEN
-
1
;
else
if
(
pre_we_w
)
fis_left
<=
fis_left
-
1
;
else
if
(
pre_we_w
)
fis_left
<=
fis_left
-
1
;
// if (fis_start) fis_first <= 1;
// else if (pre_we_w) fis_first <= 0;
if
(
fis_end
)
data_fis
<=
0
;
// else if (pre_we_w && fis_start) data_fis <= fis_data_w == 8'h46;
else
if
(
fis_start
)
data_fis
<=
fis_data_w
==
8'h46
;
if
(
rst
)
fis_we
<=
0
;
if
(
rst
)
fis_we
<=
0
;
else
if
(
fis_start
)
fis_we
<=
1
;
else
if
(
fis_start
)
fis_we
<=
1
;
else
if
((
fis_left
==
0
)
||
fis_end
)
fis_we
<=
0
;
else
if
((
fis_left
==
0
)
||
fis_end
)
fis_we
<=
0
;
...
@@ -1403,7 +1460,46 @@ module datascope_timing #(
...
@@ -1403,7 +1460,46 @@ module datascope_timing #(
else
if
(
fis_start
)
fis_run
<=
1
;
else
if
(
fis_start
)
fis_run
<=
1
;
else
if
(
fis_end
)
fis_run
<=
0
;
else
if
(
fis_end
)
fis_run
<=
0
;
fis_run_d
<=
fis_run
;
fis_run_d
<=
fis_run
;
fis_run_d2
<=
fis_run_d
;
fis_run_d3
<=
fis_run_d2
;
fis_run_d4
<=
fis_run_d3
;
fis_run_d5
<=
fis_run_d4
;
if
(
cfis
)
dw_count
<=
0
;
else
if
(
inc_dw_cntr
&&
data_fis
)
dw_count
<=
dw_count
+
1
;
if
(
rst
)
reset_link_count
<=
0
;
else
if
(
cfis
)
reset_link_count
<=
1
;
else
if
(
fis_start
&&
(
fis_data_w
==
8'h46
))
reset_link_count
<=
0
;
if
(
reset_link_count
)
link_count
<=
0
;
else
if
(
debug_link_send_data
)
link_count
<=
link_count
+
1
;
// will only be valid later, latch at next fis start
if
(
fis_start
)
link_count_latched
<=
link_count
;
if
(
reset_link_count
)
was_link_dmatp
<=
0
;
else
if
(
debug_link_dmatp
)
was_link_dmatp
<=
1
;
h2d_ready_d
<=
h2d_ready
;
if
(
rst
)
h2d_nready_cntr
<=
0
;
else
if
(
!
h2d_ready
&&
h2d_ready_d
)
h2d_nready_cntr
<=
h2d_nready_cntr
+
1
;
if
(
fis_start
)
is_cfis_r
<=
is_cfis_w
;
if
(
fis_start
&&
is_cfis_w
)
last_dma_cmd
[
23
:
16
]
<=
h2d_data
[
23
:
16
]
;
// command code
set_dma_count
<=
(
fis_len
==
3
)
&&
h2d_valid
&&
h2d_ready
&&
is_cfis_r
;
if
(
set_dma_count
)
last_dma_cmd
[
15
:
0
]
<=
fis_data
[
15
:
0
]
;
set_non_dma_act
<=
fis_start
&&
d2h_valid
&&
(
fis_data_w
!=
8'h39
)
;
if
(
set_dma_count
)
non_dma_act
<=
32'h33333333
;
else
if
(
set_non_dma_act
)
non_dma_act
<=
fis_data
;
if
(
fis_start
)
fis_len
<=
d2h_valid
?
0
:
1
;
if
(
fis_start
)
fis_len
<=
d2h_valid
?
0
:
1
;
else
if
(
pre_we_w
)
fis_len
<=
fis_len
+
1
;
else
if
(
pre_we_w
)
fis_len
<=
fis_len
+
1
;
...
...
ahci/sata_ahci_top.v
View file @
87fd75fd
...
@@ -239,6 +239,8 @@
...
@@ -239,6 +239,8 @@
reg
[
2
:
0
]
nhrst_r
;
reg
[
2
:
0
]
nhrst_r
;
wire
hrst
=
!
nhrst_r
[
2
]
;
wire
hrst
=
!
nhrst_r
[
2
]
;
wire
debug_link_send_data
;
// @sata clk - last symbol was data output
wire
debug_link_dmatp
;
// @clk (sata clk) - received CODE_DMATP
wire
[
FREQ_METER_WIDTH
-
1
:
0
]
xclk_period
;
wire
[
FREQ_METER_WIDTH
-
1
:
0
]
xclk_period
;
`ifdef
USE_DATASCOPE
`ifdef
USE_DATASCOPE
...
@@ -403,7 +405,8 @@
...
@@ -403,7 +405,8 @@
.
sctl_ipm
(
sctl_ipm
)
,
// output[3:0]
.
sctl_ipm
(
sctl_ipm
)
,
// output[3:0]
.
sctl_spd
(
sctl_spd
)
,
// output[3:0]
.
sctl_spd
(
sctl_spd
)
,
// output[3:0]
.
irq
(
irq
)
,
// output
.
irq
(
irq
)
,
// output
.
debug_link_send_data
(
debug_link_send_data
)
,
// input @posedge sata_clk - last symbol was data output (to count sent out)
.
debug_link_dmatp
(
debug_link_dmatp
)
,
// link received DMATp from device
`ifdef
USE_DATASCOPE
`ifdef
USE_DATASCOPE
.
datascope1_clk
(
datascope_clk
)
,
// input
.
datascope1_clk
(
datascope_clk
)
,
// input
.
datascope1_waddr
(
datascope_waddr
)
,
// input[9:0]
.
datascope1_waddr
(
datascope_waddr
)
,
// input[9:0]
...
@@ -489,6 +492,10 @@
...
@@ -489,6 +492,10 @@
.
txn_out
(
TXN
)
,
// output wire
.
txn_out
(
TXN
)
,
// output wire
.
rxp_in
(
RXP
)
,
// input wire
.
rxp_in
(
RXP
)
,
// input wire
.
rxn_in
(
RXN
)
,
// input wire
.
rxn_in
(
RXN
)
,
// input wire
.
debug_is_data
(
debug_link_send_data
)
,
//output @clk (sata clk) - last symbol was data output
.
debug_dmatp
(
debug_link_dmatp
)
,
// @clk (sata clk) - received CODE_DMATP
`ifdef
USE_DATASCOPE
`ifdef
USE_DATASCOPE
.
datascope_clk
(
datascope_clk
)
,
// output
.
datascope_clk
(
datascope_clk
)
,
// output
.
datascope_waddr
(
datascope_waddr
)
,
// output[9:0]
.
datascope_waddr
(
datascope_waddr
)
,
// output[9:0]
...
...
device/sata_device.v
View file @
87fd75fd
...
@@ -47,7 +47,8 @@ module sata_device(
...
@@ -47,7 +47,8 @@ module sata_device(
// reg [31:0] DEV_DATA;
// reg [31:0] DEV_DATA;
integer
DEV_DATA
;
integer
DEV_DATA
;
//`endif
//`endif
//`define TERMINATE_DMA_H2D
//`undef TERMINATE_DMA_H2D
wire
phy_ready
;
wire
phy_ready
;
wire
[
31
:
0
]
phy2dev_data
;
wire
[
31
:
0
]
phy2dev_data
;
...
@@ -569,6 +570,10 @@ task linkMonitorFIS;
...
@@ -569,6 +570,10 @@ task linkMonitorFIS;
cnt
=
cnt
+
1
;
cnt
=
cnt
+
1
;
if
(
cnt
<=
2048
)
if
(
cnt
<=
2048
)
pause
=
pause
+
receive_data_pause
[
cnt
]
;
pause
=
pause
+
receive_data_pause
[
cnt
]
;
`ifdef
TERMINATE_DMA_H2D
linkSendPrim
(
"DMAT"
)
;
`endif
end
end
end
end
@
(
posedge
clk
)
@
(
posedge
clk
)
...
...
host/link.v
View file @
87fd75fd
...
@@ -99,6 +99,8 @@ module link #(
...
@@ -99,6 +99,8 @@ module link #(
// to phy
// to phy
output
wire
[
DATA_BYTE_WIDTH
*
8
-
1
:
0
]
phy_data_out
,
output
wire
[
DATA_BYTE_WIDTH
*
8
-
1
:
0
]
phy_data_out
,
output
wire
[
DATA_BYTE_WIDTH
-
1
:
0
]
phy_isk_out
,
// charisk
output
wire
[
DATA_BYTE_WIDTH
-
1
:
0
]
phy_isk_out
,
// charisk
output
reg
debug_is_data
,
// @clk (sata clk) - last symbol was data output
output
reg
debug_dmatp
,
// @clk (sata clk) - received CODE_DMATP
// debug
// debug
output
[
31
:
0
]
debug_out
//
output
[
31
:
0
]
debug_out
//
)
;
)
;
...
@@ -580,6 +582,10 @@ begin
...
@@ -580,6 +582,10 @@ begin
end
end
endgenerate
endgenerate
always
@
(
posedge
clk
)
begin
debug_dmatp
<=
rcvd_dword
[
CODE_DMATP
]
;
end
// select which primitive shall be sent
// select which primitive shall be sent
wire
[
PRIM_NUM
-
1
:
0
]
select_prim
;
wire
[
PRIM_NUM
-
1
:
0
]
select_prim
;
assign
select_prim
[
CODE_SYNCP
]
=
~
alignes_pair
&
(
state_idle
|
state_sync_esc
|
state_rcvr_wait
|
state_reset
)
;
assign
select_prim
[
CODE_SYNCP
]
=
~
alignes_pair
&
(
state_idle
|
state_sync_esc
|
state_rcvr_wait
|
state_reset
)
;
...
@@ -618,6 +624,10 @@ always @ (posedge clk)
...
@@ -618,6 +624,10 @@ always @ (posedge clk)
{
DATA_BYTE_WIDTH
*
8
{
select_prim
[
CODE_CRC
]
}}
&
prim_data
[
CODE_CRC
]
|
{
DATA_BYTE_WIDTH
*
8
{
select_prim
[
CODE_CRC
]
}}
&
prim_data
[
CODE_CRC
]
|
{
DATA_BYTE_WIDTH
*
8
{
select_prim
[
CODE_DATA
]
}}
&
prim_data
[
CODE_DATA
]
;
{
DATA_BYTE_WIDTH
*
8
{
select_prim
[
CODE_DATA
]
}}
&
prim_data
[
CODE_DATA
]
;
always
@
(
posedge
clk
)
debug_is_data
<=
select_prim
[
CODE_DATA
]
;
always
@
(
posedge
clk
)
always
@
(
posedge
clk
)
to_phy_isk
<=
rst
|
~
select_prim
[
CODE_DATA
]
&
~
select_prim
[
CODE_CRC
]
?
{{
(
DATA_BYTE_WIDTH
-
1
)
{
1'b0
}},
1'b1
}
:
{
DATA_BYTE_WIDTH
{
1'b0
}}
;
to_phy_isk
<=
rst
|
~
select_prim
[
CODE_DATA
]
&
~
select_prim
[
CODE_CRC
]
?
{{
(
DATA_BYTE_WIDTH
-
1
)
{
1'b0
}},
1'b1
}
:
{
DATA_BYTE_WIDTH
{
1'b0
}}
;
...
...
includes/ahci_defaults.vh
View file @
87fd75fd
...
@@ -2,6 +2,6 @@
...
@@ -2,6 +2,6 @@
, .INIT_08 (256'h000000000024000600000000000000000000000080000C000000000080000800)
, .INIT_08 (256'h000000000024000600000000000000000000000080000C000000000080000800)
, .INIT_09 (256'h000000000000000000000000000000000000000000000000FFFFFFFF00000000)
, .INIT_09 (256'h000000000000000000000000000000000000000000000000FFFFFFFF00000000)
, .INIT_0B (256'h0000000000000000000000000000003300000000000000000000000000000000)
, .INIT_0B (256'h0000000000000000000000000000003300000000000000000000000000000000)
, .INIT_0C (256'h0000000000000000000000000000000000000000010100
0B
001000000001FFFE)
, .INIT_0C (256'h0000000000000000000000000000000000000000010100
11
001000000001FFFE)
, .INIT_0D (256'h000001000000000000000040000000000001FFFE000000008000000000000000)
, .INIT_0D (256'h000001000000000000000040000000000001FFFE000000008000000000000000)
, .INIT_0E (256'h0000000000000000000000000000000000000000000000000000000040000001)
, .INIT_0E (256'h0000000000000000000000000000000000000000000000000000000040000001)
includes/ahci_localparams.vh
View file @
87fd75fd
...
@@ -97,7 +97,7 @@
...
@@ -97,7 +97,7 @@
// RO: HBA Revision ID
// RO: HBA Revision ID
localparam PCI_Header__RID__RID__ADDR = 'h62;
localparam PCI_Header__RID__RID__ADDR = 'h62;
localparam PCI_Header__RID__RID__MASK = 'hff;
localparam PCI_Header__RID__RID__MASK = 'hff;
localparam PCI_Header__RID__RID__DFLT = 'h
b
;
localparam PCI_Header__RID__RID__DFLT = 'h
11
;
// RO: Base Class Code: 1 - Mass Storage Device
// RO: Base Class Code: 1 - Mass Storage Device
localparam PCI_Header__CC__BCC__ADDR = 'h62;
localparam PCI_Header__CC__BCC__ADDR = 'h62;
localparam PCI_Header__CC__BCC__MASK = 'hff000000;
localparam PCI_Header__CC__BCC__MASK = 'hff000000;
...
...
py393sata/create_ahci_registers.py
View file @
87fd75fd
...
@@ -31,7 +31,7 @@ __status__ = "Development"
...
@@ -31,7 +31,7 @@ __status__ = "Development"
"""
"""
**** Modify next value for new file versions, re-run this file *****
**** Modify next value for new file versions, re-run this file *****
"""
"""
RID
=
0x0
b
# Revision ID
RID
=
0x0
11
# Revision ID
VID
=
0xfffe
# What to use for non-PCI "vendorID"?
VID
=
0xfffe
# What to use for non-PCI "vendorID"?
DID
=
0x0001
DID
=
0x0001
SSVID
=
0xfffe
SSVID
=
0xfffe
...
...
py393sata/x393sata.py
View file @
87fd75fd
...
@@ -1497,6 +1497,17 @@ if __name__ == "__main__":
...
@@ -1497,6 +1497,17 @@ if __name__ == "__main__":
"""
"""
camogm_test -d /dev/sda2 -b 4194304 -c 30000
dd if=/dev/sda skip=257142656 count=1 | hexdump -e '"
%08
_ax: "' -e ' 16/4 "
%08
x " "
\n
"'
cat /sys/devices/soc0/amba@0/80000000.elphel-ahci/lba_current
cat /sys/devices/soc0/amba@0/80000000.elphel-ahci/lba_start
camogm_test -d /dev/sda2 -b 4194304 -c 10000
x393sata.py
x393sata.py
modprobe ahci_elphel &
modprobe ahci_elphel &
sleep 2
sleep 2
...
@@ -1520,7 +1531,8 @@ import x393_mem
...
@@ -1520,7 +1531,8 @@ import x393_mem
mem = x393_mem.X393Mem(1,0,1)
mem = x393_mem.X393Mem(1,0,1)
sata = x393sata.x393sata()
sata = x393sata.x393sata()
hex(mem.read_mem(sata.get_reg_address('PCI_Header__RID')))
hex(mem.read_mem(sata.get_reg_address('PCI_Header__RID')))
hex([((mem.read_mem(0x80000ffc) >> 10) & 0xffc) + 0x80001000,mem.mem_dump (0x80001000, 0x400,4),sata.reg_status()][0])
sata.setup_pio_read_identify_command()
sata.setup_pio_read_identify_command()
sata.dd_read_dma_ext(142615470, 512, 512)
sata.dd_read_dma_ext(142615470, 512, 512)
...
...
tb/tb_ahci.tf
View file @
87fd75fd
...
@@ -1120,6 +1120,9 @@ localparam ATA_RDMA_EXT = 'h25; // Read DMA devices that support 48-bit Addressi
...
@@ -1120,6 +1120,9 @@ localparam ATA_RDMA_EXT = 'h25; // Read DMA devices that support 48-bit Addressi
(ATA_RDMA_EXT << 16) | // Command = 0x25 (READ_DMA_EXT)
(ATA_RDMA_EXT << 16) | // Command = 0x25 (READ_DMA_EXT)
( 0 << 24); // features = 0 ?
( 0 << 24); // features = 0 ?
// All other 4 DWORDs are 0 for this command
// All other 4 DWORDs are 0 for this command
sysmem[(COMMAND_TABLE >> 2) + 3] = 1; // count
// Set PRDT (four items)
// Set PRDT (four items)
// PRDT #1
// PRDT #1
sysmem[((COMMAND_TABLE + PRD_OFFSET) >> 2) + 0] = SYS_MEM_START + IDENTIFY_BUF; // not shifted
sysmem[((COMMAND_TABLE + PRD_OFFSET) >> 2) + 0] = SYS_MEM_START + IDENTIFY_BUF; // not shifted
...
@@ -1178,6 +1181,7 @@ localparam ATA_RDMA_EXT = 'h25; // Read DMA devices that support 48-bit Addressi
...
@@ -1178,6 +1181,7 @@ localparam ATA_RDMA_EXT = 'h25; // Read DMA devices that support 48-bit Addressi
sysmem[(COMMAND_TABLE >> 2) + 1] = lba & 'hffffff; // 24 LSBs of LBA (48-bit require different ATA command)
sysmem[(COMMAND_TABLE >> 2) + 1] = lba & 'hffffff; // 24 LSBs of LBA (48-bit require different ATA command)
sysmem[(COMMAND_TABLE >> 2) + 3] = 1; // 1 logical sector (0 means 256)
sysmem[(COMMAND_TABLE >> 2) + 3] = 1; // 1 logical sector (0 means 256)
// All other DWORDs are 0 for this command
// All other DWORDs are 0 for this command
sysmem[(COMMAND_TABLE >> 2) + 3] = 1; // count
// Set PRDT (four items)
// Set PRDT (four items)
// PRDT #1
// PRDT #1
sysmem[((COMMAND_TABLE + PRD_OFFSET) >> 2) + 0] = SYS_MEM_START + IDENTIFY_BUF; // not shifted
sysmem[((COMMAND_TABLE + PRD_OFFSET) >> 2) + 0] = SYS_MEM_START + IDENTIFY_BUF; // not shifted
...
@@ -1227,6 +1231,7 @@ localparam ATA_RDMA_EXT = 'h25; // Read DMA devices that support 48-bit Addressi
...
@@ -1227,6 +1231,7 @@ localparam ATA_RDMA_EXT = 'h25; // Read DMA devices that support 48-bit Addressi
sysmem[(COMMAND_TABLE >> 2) + 1] = lba & 'hffffff; // 24 LSBs of LBA (48-bit require different ATA command)
sysmem[(COMMAND_TABLE >> 2) + 1] = lba & 'hffffff; // 24 LSBs of LBA (48-bit require different ATA command)
sysmem[(COMMAND_TABLE >> 2) + 3] = 1; // 1 logical sector (0 means 256)
sysmem[(COMMAND_TABLE >> 2) + 3] = 1; // 1 logical sector (0 means 256)
// All other DWORDs are 0 for this command
// All other DWORDs are 0 for this command
sysmem[(COMMAND_TABLE >> 2) + 3] = 1; // count
// Set PRDT (four items)
// Set PRDT (four items)
// PRDT #1
// PRDT #1
sysmem[((COMMAND_TABLE + PRD_OFFSET) >> 2) + 0] = SYS_MEM_START + IDENTIFY_BUF; // not shifted
sysmem[((COMMAND_TABLE + PRD_OFFSET) >> 2) + 0] = SYS_MEM_START + IDENTIFY_BUF; // not shifted
...
...
tb_ahci_01.sav
View file @
87fd75fd
This diff is collapsed.
Click to expand it.
x393_sata.bit
View file @
87fd75fd
No preview for this file type
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