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
09386747
Commit
09386747
authored
Jan 21, 2016
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
connecting AHCI to link/phy layers
parent
0f0cf866
Changes
6
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
302 additions
and
121 deletions
+302
-121
ahci_fis_transmit.v
ahci/ahci_fis_transmit.v
+31
-14
ahci_fsm.v
ahci/ahci_fsm.v
+10
-10
ahci_sata_layers.v
ahci/ahci_sata_layers.v
+235
-83
ahci_top.v
ahci/ahci_top.v
+15
-11
link.v
host/link.v
+7
-2
sata_host.v
host/sata_host.v
+4
-1
No files found.
ahci/ahci_fis_transmit.v
View file @
09386747
...
...
@@ -33,21 +33,25 @@ module ahci_fis_transmit #(
input
fetch_cmd
,
// Enter p:FetchCmd, fetch command header (from the register memory, prefetch command FIS)
// wait for either fetch_cmd_busy == 0 or pCmdToIssue ==1 after fetch_cmd
input
cfis_xmit
,
// transmit command (wait for dma_ct_busy == 0)
input
dx_
trans
mit
,
// send FIS header DWORD, (just 0x46), then forward DMA data
input
dx_
x
mit
,
// send FIS header DWORD, (just 0x46), then forward DMA data
// transmit until error, 2048DWords or pDmaXferCnt
input
atapi_xmit
,
// trasmit ATAPI command FIS
output
reg
done
,
output
reg
done
,
// for fetch_cmd - dma_start, for *_xmit - xmit_ok, xmit_err, syncesc_recv or xrdy_collision
output
reg
busy
,
input
clearCmdToIssue
,
// From CFIS:SUCCESS
output
pCmdToIssue
,
// AHCI port variable
// output dmaCntrZero, // DMA counter is zero - would be a duplicate to the one in receive module and dwords_sent output
// output reg fetch_cmd_busy, // does not include prefetching CT - now just use busy/done
input
syncesc_recv
,
// These two inputs interrupt transmit
// Should wait for xmit_ok? Timeout? Timeout will be handled by software, so just wait for OK or some error
input
xmit_ok
,
// FIS transmission acknowledged OK
input
xmit_err
,
//
output
[
1
:
0
]
dx_err
,
// bit 0 - syncesc_recv, 1 - xmit_err (valid @ xmit_err and later, reset by new command)
input
syncesc_recv
,
// These two inputs interrupt transmit
input
xrdy_collision
,
output
[
2
:
0
]
dx_err
,
// bit 0 - syncesc_recv, 1 - xmit_err, 2 - collision (valid @ xmit_err and later, reset by new command)
output
[
15
:
0
]
ch_prdtl
,
// Physical region descriptor table length (in entries, 0 is 0)
output
ch_c
,
// Clear busy upon R_OK for this FIS
...
...
@@ -89,7 +93,7 @@ module ahci_fis_transmit #(
// Data System memory or FIS -> device
output
reg
[
31
:
0
]
todev_data
,
// 32-bit data from the system memory to HBA (dma data)
output
reg
[
1
:
0
]
todev_type
,
// 0 - data, 1 - FIS head, 2 - FIS
END (make FIS_Last?
)
output
reg
[
1
:
0
]
todev_type
,
// 0 - data, 1 - FIS head, 2 - FIS
LAST
)
output
todev_valid
,
// output register full
input
todev_ready
// send FIFO has room for data (>= 8? dwords)
...
...
@@ -152,13 +156,16 @@ module ahci_fis_transmit #(
reg
dx_fis_pend_r
;
// waiting to send first DWORD of the H2D data transfer
wire
dx_dma_last_w
;
// sending last adat word
reg
dx_busy_r
;
reg
[
1
:
0
]
dx_err_r
;
wire
any_cmd_start
=
fetch_cmd
||
cfis_xmit
||
dx_transmit
||
atapi_xmit
;
wire
done_w
=
dx_dma_last_w
||
((
|
dx_err_r
)
&&
dx_busy_r
)
||
chead_done_w
||
acfis_xmit_end
||
dma_start
;
// done on last transmit or error
reg
[
2
:
0
]
dx_err_r
;
reg
xmit_ok_r
;
wire
any_cmd_start
=
fetch_cmd
||
cfis_xmit
||
dx_xmit
||
atapi_xmit
;
// wire done_w = dx_dma_last_w || ((|dx_err_r) && dx_busy_r) || chead_done_w || acfis_xmit_end || dma_start; // done on last transmit or error
// dma_start ends 'fetch_cmd'
wire
done_w
=
xmit_ok_r
||
((
|
dx_err_r
)
&&
dx_busy_r
)
||
dma_start
;
// done on last transmit or error
reg
fetch_cmd_busy_r
;
assign
todev_valid
=
todev_full_r
;
assign
dma_re
=
dma_re_w
;
assign
reg_re
=
reg_re_r
[
1
:
0
]
;
...
...
@@ -283,15 +290,15 @@ module ahci_fis_transmit #(
//TODO: update xfer length, prdtl (only after R_OK) - yes, do it outside
if
(
dx_
transmit
)
dx_dwords_left
[
11
:
2
]
<=
(
|
xfer_cntr
[
31
:
11
])
?
10'h200
:{
1'b0
,
xfer_cntr
[
10
:
2
]
};
if
(
dx_
xmit
)
dx_dwords_left
[
11
:
2
]
<=
(
|
xfer_cntr
[
31
:
11
])
?
10'h200
:{
1'b0
,
xfer_cntr
[
10
:
2
]
};
else
if
(
dma_re_w
)
dx_dwords_left
[
11
:
2
]
<=
dx_dwords_left
[
11
:
2
]
-
1
;
if
(
dx_
transmit
)
dwords_sent
<=
0
;
if
(
dx_
xmit
)
dwords_sent
<=
0
;
else
if
(
dma_re_w
)
dwords_sent
<=
dwords_sent
+
1
;
// send FIS header
if
(
hba_rst
||
write_or_w
)
dx_fis_pend_r
<=
0
;
else
if
(
dx_
transmit
)
dx_fis_pend_r
<=
1
;
else
if
(
dx_
xmit
)
dx_fis_pend_r
<=
1
;
if
(
hba_rst
||
dx_dma_last_w
||
(
|
dx_err_r
))
dma_en_r
<=
0
;
else
if
(
dx_fis_pend_r
&&
write_or_w
)
dma_en_r
<=
1
;
...
...
@@ -303,9 +310,14 @@ module ahci_fis_transmit #(
if
(
hba_rst
||
any_cmd_start
)
dx_err_r
[
1
]
<=
0
;
else
if
(
xmit_err
)
dx_err_r
[
1
]
<=
1
;
if
(
hba_rst
)
dx_busy_r
<=
0
;
else
if
(
dx_transmit
)
dx_busy_r
<=
1
;
else
if
(
dx_dma_last_w
||
(
|
dx_err_r
))
dx_busy_r
<=
0
;
if
(
hba_rst
||
any_cmd_start
)
dx_err_r
[
2
]
<=
0
;
else
if
(
xrdy_collision
)
dx_err_r
[
2
]
<=
1
;
if
(
hba_rst
)
dx_busy_r
<=
0
;
// sending CFIS, AFIS or data FIS (until error or R_OK)
// else if (dx_xmit) dx_busy_r <= 1;
// else if (dx_dma_last_w || (|dx_err_r)) dx_busy_r <= 0;
else
if
(
dx_xmit
||
acfis_xmit_start_r
)
dx_busy_r
<=
1
;
else
if
(
xmit_ok
||
(
|
dx_err_r
))
dx_busy_r
<=
0
;
dma_prd_start
<=
(
dma_start
&&
(
PREFETCH_ALWAYS
||
ch_p_r
||
!
ch_w_r
))
||
// device read may prefetch just prd addresses
(
dx_fis_pend_r
&&
write_or_w
)
;
// enable PRD read now (if it was not already done)
...
...
@@ -317,6 +329,11 @@ module ahci_fis_transmit #(
else
if
(
any_cmd_start
)
busy
<=
1
;
else
if
(
done_w
)
busy
<=
0
;
if
(
hba_rst
)
xmit_ok_r
<=
0
;
else
xmit_ok_r
<=
dx_busy_r
&&
!
(
|
dx_err_r
)
&&
xmit_ok
;
dma_cmd_abort
<=
done_w
&&
(
|
dx_err_r
)
;
...
...
ahci/ahci_fsm.v
View file @
09386747
...
...
@@ -48,7 +48,7 @@ module ahci_fsm
output
comreset_send
,
// Not possible yet?
input
cominit_got
,
// asynchronously jumps to P:Cominit state
output
set_offline
,
// electrically idle
input
x_rdy_collision
,
// X_RDY/X_RDY collision on interface
//
input x_rdy_collision, // X_RDY/X_RDY collision on interface
output
send_R_OK
,
// Should it be originated in this layer SM?
output
send_R_ERR
,
...
...
@@ -213,7 +213,7 @@ module ahci_fsm
output
fetch_cmd
,
// Enter p:FetchCmd, fetch command header (from the register memory, prefetch command FIS)
// wait for either fetch_cmd_busy == 0 or pCmdToIssue ==1 after fetch_cmd
output
cfis_xmit
,
// transmit command (wait for dma_ct_busy == 0)
output
dx_
transmit
,
// send FIS header DWORD, (just 0x46), then forward DMA data
output
dx_
xmit
,
// send FIS header DWORD, (just 0x46), then forward DMA data
// transmit until error, 2048DWords or pDmaXferCnt
output
atapi_xmit
,
// tarsmit ATAPI command FIS
input
xmit_done
,
...
...
@@ -224,7 +224,7 @@ module ahci_fsm
// output dmaCntrZero, // DMA counter is zero - would be a duplicate to the one in receive module and dwords_sent output
// input syncesc_recv, // These two inputs interrupt transmit
// input xmit_err, //
input
[
1
:
0
]
dx_err
,
// bit 0 - syncesc_recv, 1 - xmit_err
(valid @ xmit_err and later, reset by new command)
input
[
2
:
0
]
dx_err
,
// bit 0 - syncesc_recv, 1 - xmit_err, 2 - X_RDY/X_RDY collision
(valid @ xmit_err and later, reset by new command)
/// input [15:0] ch_prdtl, // Physical region descriptor table length (in entries, 0 is 0)
input
ch_c
,
// Clear busy upon R_OK for this FIS
...
...
@@ -272,7 +272,7 @@ module ahci_fsm
reg
async_from_st
;
// chnge to multi-bit if there will be more sources for async transitions
wire
asynq_rq
=
cominit_got
||
pcmd_st_cleared
;
wire
async_ackn
=
!
fsm_preload
&&
async_pend_r
[
0
]
&&
((
fsm_actions
&&
!
update_busy
&&
!
fsm_act_busy
)
||
fsm_transitions
[
0
])
;
// OK to process async jump
reg
x_rdy_collision_pend
;
//
reg x_rdy_collision_pend;
reg
syncesc_send_pend
;
// waiting for 'syncesc_send' confiramtion 'syncesc_send_done'
reg
[
1
:
0
]
phy_ready_prev
;
// previous state of phy_ready / speed
reg
phy_ready_chng_r
;
// pulse when phy_ready changes
...
...
@@ -353,8 +353,8 @@ module ahci_fsm
else
async_pend_r
<=
{
async_pend_r
[
0
]
,
asynq_rq
|
(
async_pend_r
[
0
]
&
~
async_ackn
)
};
if
(
hba_rst
||
pcmd_cr_set
)
x_rdy_collision_pend
<=
0
;
else
if
(
x_rdy_collision
)
x_rdy_collision_pend
<=
1
;
//
if (hba_rst || pcmd_cr_set) x_rdy_collision_pend <= 0;
//
else if (x_rdy_collision) x_rdy_collision_pend <= 1;
if
(
hba_rst
||
syncesc_send_done
)
syncesc_send_pend
<=
0
;
else
if
(
syncesc_send
)
syncesc_send_pend
<=
1
;
...
...
@@ -435,7 +435,7 @@ module ahci_fsm
.
FETCH_CMD
(
fetch_cmd
)
,
// output reg
.
ATAPI_XMIT
(
atapi_xmit
)
,
// output reg
.
CFIS_XMIT
(
cfis_xmit
)
,
// output reg
.
DX_XMIT
(
dx_
transmit
)
,
// output reg
.
DX_XMIT
(
dx_
xmit
)
,
// output reg
//FIS RECEIVE/WAIT DONE
.
GET_DATA_FIS
(
get_data_fis
)
,
// output reg
.
GET_DSFIS
(
get_dsfis
)
,
// output reg
...
...
@@ -500,7 +500,7 @@ module ahci_fsm
// DMA
.
DMA_PRD_IRQ_PEND
(
dma_prd_irq_pend
)
,
// input
// SATA TRANSPORT/LINK/PHY
.
X_RDY_COLLISION
(
x_rdy_collision_pend
)
// input
.
X_RDY_COLLISION
(
dx_err
[
2
])
//
x_rdy_collision_pend) // input
)
;
...
...
ahci/ahci_sata_layers.v
View file @
09386747
This diff is collapsed.
Click to expand it.
ahci/ahci_top.v
View file @
09386747
...
...
@@ -143,8 +143,9 @@ module ahci_top#(
// communication with transport/link/phys layers
// input phy_rst, // frome phy, as a response to hba_arst || port_arst. It is deasserted when clock is stable
input
[
1
:
0
]
phy_ready
,
// 0 - not ready, 1..3 - negotiated speed
input
syncesc_recv
,
// These two inputs interrupt transmit
input
xmit_ok
,
// FIS transmission acknowledged OK
input
xmit_err
,
// Error during sending of a FIS
input
syncesc_recv
,
// These two inputs interrupt transmit
output
syncesc_send
,
// Send sync escape
input
syncesc_send_done
,
// "SYNC escape until the interface is quiescent..."
output
comreset_send
,
// Not possible yet?
...
...
@@ -317,7 +318,7 @@ module ahci_top#(
wire
fsnd_fetch_cmd
;
// Enter p:FetchCmd, fetch command header (from the register memory, prefetch command FIS)
// wait for either fetch_cmd_busy == 0 or pCmdToIssue ==1 after fetch_cmd
wire
fsnd_cfis_xmit
;
// transmit command (wait for dma_ct_busy == 0)
wire
fsnd_dx_
transmit
;
// send FIS header DWORD, (just 0x46), then forward DMA data
wire
fsnd_dx_
xmit
;
// send FIS header DWORD, (just 0x46), then forward DMA data
// transmit until error, 2048DWords or pDmaXferCnt
wire
fsnd_atapi_xmit
;
// tarsmit ATAPI command FIS
// responses fsm <- ahc_fis_transmit
...
...
@@ -327,7 +328,7 @@ module ahci_top#(
wire
fsnd_clearCmdToIssue
;
// From CFIS:SUCCESS
// State variables fsm <- ahc_fis_transmit
wire
fsnd_pCmdToIssue
;
// AHCI port variable
wire
[
1
:
0
]
fsnd_dx_err
;
// bit 0 - syncesc_recv, 1 - xmit_err
(valid @ xmit_err and later, reset by new command)
wire
[
2
:
0
]
fsnd_dx_err
;
// bit 0 - syncesc_recv, 1 - xmit_err 2 - X-RDY/X_RDY collision
(valid @ xmit_err and later, reset by new command)
wire
fsnd_ch_c
;
// Clear busy upon R_OK for this FIS
wire
fsnd_ch_b
;
// Built-in self test command
wire
fsnd_ch_r
;
// reset - may need to send SYNC escape before this command
...
...
@@ -444,7 +445,7 @@ module ahci_top#(
.
syncesc_send_done
(
syncesc_send_done
)
,
// input
.
cominit_got
(
cominit_got
)
,
// input
.
set_offline
(
set_offline
)
,
// output
.
x_rdy_collision
(
x_rdy_collision
)
,
// input
//
.x_rdy_collision (x_rdy_collision), // input
.
send_R_OK
(
send_R_OK
)
,
// output
.
send_R_ERR
(
send_R_ERR
)
,
// output
...
...
@@ -572,7 +573,7 @@ module ahci_top#(
.
fetch_cmd
(
fsnd_fetch_cmd
)
,
// output
.
cfis_xmit
(
fsnd_cfis_xmit
)
,
// output
.
dx_
transmit
(
fsnd_dx_transmit
)
,
// output
.
dx_
xmit
(
fsnd_dx_xmit
)
,
// output
.
atapi_xmit
(
fsnd_atapi_xmit
)
,
// output
.
xmit_done
(
fsnd_done
)
,
// input
/// .xmit_busy (fsnd_busy), // input
...
...
@@ -901,20 +902,23 @@ module ahci_top#(
.
READ_CT_LATENCY
(
READ_CT_LATENCY
)
,
.
ADDRESS_BITS
(
ADDRESS_BITS
)
)
ahci_fis_transmit_i
(
.
hba_rst
(
mrst
)
,
// input
// .hba_rst (mrst), // input TODO: Reset when !PxCMD.ST? pcmd_st
.
hba_rst
(
mrst
||
!
pcmd_st
)
,
// input TODO: Reset when !PxCMD.ST? pcmd_st
.
mclk
(
mclk
)
,
// input
.
fetch_cmd
(
fsnd_fetch_cmd
)
,
// input
.
cfis_xmit
(
fsnd_cfis_xmit
)
,
// input
.
dx_
transmit
(
fsnd_dx_transmit
)
,
// input
.
dx_
xmit
(
fsnd_dx_xmit
)
,
// input
.
atapi_xmit
(
fsnd_atapi_xmit
)
,
// input
.
done
(
fsnd_done
)
,
// output reg
.
busy
()
,
/// fsnd_busy), // output reg
.
clearCmdToIssue
(
fsnd_clearCmdToIssue
)
,
// input
.
pCmdToIssue
(
fsnd_pCmdToIssue
)
,
// output
.
syncesc_recv
(
syncesc_recv
)
,
// input
.
xmit_ok
(
xmit_ok
)
,
// input
.
xmit_err
(
xmit_err
)
,
// input
.
syncesc_recv
(
syncesc_recv
)
,
// input
.
xrdy_collision
(
x_rdy_collision
)
,
// input
.
dx_err
(
fsnd_dx_err
)
,
// output[1:0]
.
ch_prdtl
(
prdtl
)
,
// output[15:0]
.
ch_c
(
fsnd_ch_c
)
,
// output
...
...
host/link.v
View file @
09386747
...
...
@@ -88,6 +88,8 @@ module link #(
output
wire
incom_done
,
// if incoming transition had errors
output
wire
incom_invalidate
,
// particular type - got sync escape
output
wire
incom_sync_escape
,
// transport layer responds on a completion of a FIS
input
wire
incom_ack_good
,
input
wire
incom_ack_bad
,
...
...
@@ -611,8 +613,11 @@ assign incom_start = set_rcvr_wait & ~alignes_pair;
// ... and processed
assign
incom_done
=
set_rcvr_goodcrc
&
~
alignes_pair
;
// or the FIS had errors
assign
incom_invalidate
=
state_rcvr_eof
&
crc_bad
&
~
alignes_pair
|
state_rcvr_data
&
dword_val
&
rcvd_dword
[
CODE_WTRMP
]
|
(
state_rcvr_wait
|
state_rcvr_rdy
|
state_rcvr_data
|
state_rcvr_rhold
|
state_rcvr_shold
|
state_rcvr_eof
|
state_rcvr_goodcrc
)
&
got_escape
;
//assign incom_invalidate = state_rcvr_eof & crc_bad & ~alignes_pair | state_rcvr_data & dword_val & rcvd_dword[CODE_WTRMP]
// | (state_rcvr_wait | state_rcvr_rdy | state_rcvr_data | state_rcvr_rhold | state_rcvr_shold | state_rcvr_eof | state_rcvr_goodcrc) & got_escape;
// Separating different types of errors, sync_escape from other problems. TODO: route individual errors to set SERR bits
assign
incom_invalidate
=
state_rcvr_eof
&
crc_bad
&
~
alignes_pair
|
state_rcvr_data
&
dword_val
&
rcvd_dword
[
CODE_WTRMP
]
;
assign
incom_sync_escape
=
(
state_rcvr_wait
|
state_rcvr_rdy
|
state_rcvr_data
|
state_rcvr_rhold
|
state_rcvr_shold
|
state_rcvr_eof
|
state_rcvr_goodcrc
)
&
got_escape
;
// 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
]
;
...
...
host/sata_host.v
View file @
09386747
...
...
@@ -386,6 +386,7 @@ wire ll2tl_incom_start;
wire
ll2tl_incom_done
;
// LL reports of errors in current FIS
wire
ll2tl_incom_invalidate
;
// TODO
wire
ll2tl_incom_sync_escape
;
// TL analyzes FIS and returnes if FIS makes sense.
wire
ll2tl_incom_ack_good
;
// ... and if it doesn't
...
...
@@ -452,7 +453,7 @@ transport transport(
// LL reports of a completion of an incoming frame transmission.
.
incom_done
(
ll2tl_incom_done
)
,
// LL reports of errors in current FIS
.
incom_invalidate
(
ll2tl_incom_invalidate
)
,
// TODO
.
incom_invalidate
(
ll2tl_incom_invalidate
||
ll2tl_incom_sync_escape
)
,
// TODO
// TL analyzes FIS and returnes if FIS makes sense.
.
incom_ack_good
(
ll2tl_incom_ack_good
)
,
// ... and if it doesn't
...
...
@@ -648,6 +649,8 @@ link link(
.
incom_done
(
ll2tl_incom_done
)
,
// if incoming transition had errors
.
incom_invalidate
(
ll2tl_incom_invalidate
)
,
// if incoming got sync escape
.
incom_sync_escape
(
ll2tl_incom_sync_escape
)
,
// output wire
// transport layer responds on a completion of a FIS
.
incom_ack_good
(
ll2tl_incom_ack_good
)
,
.
incom_ack_bad
(
ll2tl_incom_ack_bad
)
,
...
...
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