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
4bf4f348
Commit
4bf4f348
authored
Jan 17, 2016
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
continue on sequencer code and related changes
parent
927f8201
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
222 additions
and
59 deletions
+222
-59
ahci_fis_receive.v
ahci/ahci_fis_receive.v
+31
-30
ahci_fis_transmit.v
ahci/ahci_fis_transmit.v
+5
-2
ahci_fsm.v
ahci/ahci_fsm.v
+17
-5
ahci_top.v
ahci/ahci_top.v
+24
-10
ahci_fsm_sequence.py
helpers/ahci_fsm_sequence.py
+145
-12
No files found.
ahci/ahci_fis_receive.v
View file @
4bf4f348
...
...
@@ -37,9 +37,6 @@ module ahci_fis_receive#(
// Control Interface
output
reg
fis_first_vld
,
// fis_first contains valid FIS header, reset by get_*
// Receiving FIS
input
set_update_sig
,
// when set, enables get_sig (and resets itself)
output
pUpdateSig
,
// state variable
input
get_sig
,
// update signature
input
get_dsfis
,
input
get_psfis
,
input
get_rfis
,
...
...
@@ -52,7 +49,11 @@ module ahci_fis_receive#(
output
reg
fis_ok
,
// FIS done, checksum OK reset by starting a new get FIS
output
reg
fis_err
,
// FIS done, checksum ERROR reset by starting a new get FIS
output
fis_ferr
,
// FIS done, fatal error - FIS too long
input
set_update_sig
,
// when set, enables update_sig (and resets itself)
output
pUpdateSig
,
// state variable
output
reg
sig_available
,
// device signature a ailable
// next commands use register address/data/we for 1 clock cycle - after next to command (commnd - t0, we - t2)
input
update_sig
,
// update signature - now after get_rfis, after FIS is already received
input
update_err_sts
,
// update PxTFD.STS and PxTFD.ERR from the last received regs d2h
input
update_pio
,
// update PxTFD.STS and PxTFD.ERR from pio_* (entry PIO:Update)
input
update_prdbc
,
// update PRDBC in registers
...
...
@@ -168,7 +169,7 @@ localparam DATA_TYPE_ERR = 3;
wire
reg_we_w
;
reg
[
3
:
0
]
updat
e_sig
;
reg
[
3
:
0
]
stor
e_sig
;
reg
[
5
:
0
]
reg_ds
;
reg
[
4
:
0
]
reg_ps
;
reg
reg_d2h
;
...
...
@@ -179,6 +180,7 @@ localparam DATA_TYPE_ERR = 3;
reg
[
15
:
0
]
tf_err_sts
;
reg
update_err_sts_r
;
reg
update_sig_r
;
// reg update_pio_r;
reg
update_prdbc_r
;
reg
get_fis_busy_r
;
...
...
@@ -187,7 +189,8 @@ localparam DATA_TYPE_ERR = 3;
reg
[
7
:
0
]
pio_es_r
;
// value of PIO E_Status
reg
[
7
:
0
]
pio_err_r
;
reg
pUpdateSig_r
=
1
;
// state variable
reg
pUpdateSig_r
=
1
;
// state variable
reg
[
31
:
0
]
sig_r
;
// signature register, save at
// Forward data to DMA (dev->mem) engine
assign
dma_in_valid
=
dma_in_ready
&&
(
hba_data_in_type
==
DATA_TYPE_DMA
)
&&
data_in_ready
&&
!
too_long_err
;
...
...
@@ -226,27 +229,24 @@ localparam DATA_TYPE_ERR = 3;
(
wreg_we_r
&&
dwords_over
))
too_long_err
<=
1
;
if
(
get_fis
)
begin
reg_addr_r
<=
(
{
ADDRESS_BITS
{
get_sig
}}
&
(
PXSIG_OFFS32
))
|
(
{
ADDRESS_BITS
{
get_dsfis
}}
&
(
FB_OFFS32
+
DSFIS32
))
|
reg_addr_r
<=
(
{
ADDRESS_BITS
{
get_dsfis
}}
&
(
FB_OFFS32
+
DSFIS32
))
|
(
{
ADDRESS_BITS
{
get_psfis
}}
&
(
FB_OFFS32
+
PSFIS32
))
|
(
{
ADDRESS_BITS
{
get_rfis
}}
&
(
FB_OFFS32
+
RFIS32
))
|
(
{
ADDRESS_BITS
{
get_sdbfis
}}
&
(
FB_OFFS32
+
SDBFIS32
))
|
(
{
ADDRESS_BITS
{
get_ufis
}}
&
(
FB_OFFS32
+
UFIS32
))
;
fis_dcount
<=
(
{
4
{
get_sig
}}
&
RFIS32_LENM1
)
|
(
{
4
{
get_dsfis
}}
&
DSFIS32_LENM1
)
|
fis_dcount
<=
(
{
4
{
get_dsfis
}}
&
DSFIS32_LENM1
)
|
(
{
4
{
get_psfis
}}
&
PSFIS32_LENM1
)
|
(
{
4
{
get_rfis
}}
&
RFIS32_LENM1
)
|
(
{
4
{
get_sdbfis
}}
&
SDBFIS32_LENM1
)
|
(
{
4
{
get_ufis
}}
&
UFIS32_LENM1
)
|
(
{
4
{
get_data_fis
}}
&
DMAH_LENM1
)
|
(
{
4
{
get_ignore
}}
&
IGNORE_LENM1
)
;
// fis_save <= pcmd_fre && !get_data_fis && !get_ignore && !get_sig;
// save signature FIS to memory if waiting (if not - ignore FIS)
// for non-signature /non-data - obey pcmd_fre
fis_save
<=
get_sig
?
pUpdateSig_r
:
(
pcmd_fre
&&
!
get_data_fis
&&
!
get_ignore
)
;
fis_save
<=
(
pUpdateSig_r
||
get_rfis
)
||
(
pcmd_fre
&&
!
get_data_fis
&&
!
get_ignore
)
;
is_data_fis
<=
get_data_fis
;
update_sig
<=
((
get_sig
&&
pUpdateSig_r
)
?
1
:
0
)
;
store_sig
<=
(
get_rfis
)
?
1
:
0
;
reg_ds
<=
get_dsfis
?
1
:
0
;
reg_ps
<=
get_psfis
?
1
:
0
;
reg_d2h
<=
get_rfis
?
1
:
0
;
...
...
@@ -254,7 +254,7 @@ localparam DATA_TYPE_ERR = 3;
end
else
if
(
wreg_we_r
&&
!
dwords_over
)
begin
fis_dcount
<=
fis_dcount
-
1
;
// update even if not writing to registers
if
(
fis_save
)
reg_addr_r
<=
reg_addr_r
+
1
;
// update only when writing to registers
update_sig
<=
updat
e_sig
<<
1
;
store_sig
<=
stor
e_sig
<<
1
;
reg_ds
<=
reg_ds
<<
1
;
reg_ps
<=
reg_ps
<<
1
;
reg_d2h
<=
0
;
...
...
@@ -289,19 +289,16 @@ localparam DATA_TYPE_ERR = 3;
if
(
hba_rst
||
get_fis
)
fis_err
<=
0
;
else
if
(
fis_end_w
)
fis_err
<=
hba_data_in_type
!=
DATA_TYPE_OK
;
if
(
reg_we_w
)
reg_data
[
31
:
8
]
<=
hba_data_in
[
31
:
8
]
;
else
if
(
update_sig
[
1
])
reg_data
[
31
:
8
]
<=
hba_data_in
[
23
:
0
]
;
else
if
(
update_err_sts_r
)
reg_data
[
31
:
8
]
<=
{
16'b0
,
tf_err_sts
[
15
:
8
]
};
// else if (update_pio_r) reg_data[31:8] <= {16'b0,pio_err_r[7:0]};
else
if
(
update_prdbc_r
)
reg_data
[
31
:
8
]
<=
{
xfer_cntr_r
[
31
:
8
]
};
if
(
reg_we_w
)
reg_data
[
7
:
0
]
<=
hba_data_in
[
7
:
0
]
;
else
if
(
update_sig
[
3
])
reg_data
[
7
:
0
]
<=
hba_data_in
[
7
:
0
]
;
else
if
(
update_err_sts_r
)
reg_data
[
7
:
0
]
<=
tf_err_sts
[
7
:
0
]
;
// else if (update_pio_r) reg_data[ 7:0] <= pio_es_r [ 7:0];
else
if
(
update_prdbc_r
)
reg_data
[
7
:
0
]
<=
{
xfer_cntr_r
[
7
:
2
]
,
2'b0
};
if
(
reg_we_w
)
reg_data
<=
hba_data_in
;
else
if
(
update_err_sts_r
)
reg_data
<=
{
16'b0
,
tf_err_sts
};
else
if
(
update_sig_r
)
reg_data
<=
sig_r
;
else
if
(
update_prdbc_r
)
reg_data
<=
{
xfer_cntr_r
[
31
:
2
]
,
2'b0
};
if
(
store_sig
[
1
])
sig_r
[
31
:
8
]
<=
hba_data_in
[
23
:
0
]
;
if
(
store_sig
[
3
])
sig_r
[
7
:
0
]
<=
hba_data_in
[
7
:
0
]
;
if
(
reg_d2h
||
update_sig
[
0
])
tf_err_sts
<=
hba_data_in
[
15
:
0
]
;
if
(
reg_d2h
)
tf_err_sts
<=
hba_data_in
[
15
:
0
]
;
// Sets pPioErr[pPmpCur] to Error field of the FIS
// Updates PxTFD.STS.ERR with pPioErr[pPmpCur] ??
else
if
(
reg_ps
[
0
])
tf_err_sts
<=
{
hba_data_in
[
31
:
24
]
,
hba_data_in
[
23
:
16
]
};
...
...
@@ -311,12 +308,13 @@ localparam DATA_TYPE_ERR = 3;
tf_err_sts
<=
tf_err_sts
&
{
8'hff
,
clear_bsy_drq
,
3'h7
,
clear_bsy_drq
,
3'h7
}
|
{
8'h0
,
set_bsy
,
3'h0
,
clear_bsy_set_drq
,
3'h0
};
else
if
(
set_sts_7f
||
set_sts_80
)
tf_err_sts
<=
{
tf_err_sts
[
15
:
8
]
,
set_sts_80
,{
7
{
set_sts_7f
}}}
;
reg_we
<=
reg_we_w
||
update_sig
[
3
]
||
update_err_sts_r
||
update_prdbc_r
;
reg_we
<=
reg_we_w
||
update_sig
_r
||
update_err_sts_r
||
update_prdbc_r
;
if
(
reg_we_w
||
update_sig
[
3
])
reg_addr
<=
reg_addr_r
;
if
(
reg_we_w
)
reg_addr
<=
reg_addr_r
;
else
if
(
update_err_sts_r
)
reg_addr
<=
PXTFD_OFFS32
;
else
if
(
update_sig_r
)
reg_addr
<=
PXSIG_OFFS32
;
else
if
(
update_prdbc_r
)
reg_addr
<=
CLB_OFFS32
+
1
;
// location of PRDBC
if
(
reg_d2h
||
reg_sdb
||
reg_ds
[
0
])
fis_i
<=
hba_data_in
[
14
]
;
if
(
reg_sdb
)
sdb_n
<=
hba_data_in
[
15
]
;
if
(
reg_ds
[
0
])
{
dma_a
,
dma_d
}
<=
{
hba_data_in
[
15
]
,
hba_data_in
[
13
]
};
...
...
@@ -341,13 +339,16 @@ localparam DATA_TYPE_ERR = 3;
update_err_sts_r
<=
update_pio
||
update_err_sts
||
clear_bsy_drq
||
set_bsy
||
set_sts_7f
||
set_sts_80
;
// update_pio_r <= update_pio;
update_prdbc_r
<=
update_prdbc
;
// same latency as update_err_sts
update_sig_r
<=
update_sig
&&
pUpdateSig_r
;
// do not update if not requested
if
(
hba_rst
||
update_pio
)
pPioXfer
<=
0
;
else
if
(
reg_ps
[
4
])
pPioXfer
<=
1
;
if
(
hba_rst
||
update_pio
)
pPioXfer
<=
0
;
else
if
(
reg_ps
[
4
])
pPioXfer
<=
1
;
if
(
hba_rst
||
set_update_sig
)
pUpdateSig_r
<=
1
;
else
if
(
update_sig
[
3
])
pUpdateSig_r
<=
0
;
else
if
(
update_sig
)
pUpdateSig_r
<=
0
;
if
(
hba_rst
||
update_sig
)
sig_available
<=
0
;
else
if
(
store_sig
[
3
])
sig_available
<=
1
;
// Maybe it is not needed if the fsm will send this pulse?
// data_in_words_apply <= dma_in_stop && (hba_data_in_type == DATA_TYPE_OK);
...
...
ahci/ahci_fis_transmit.v
View file @
4bf4f348
...
...
@@ -35,7 +35,7 @@ module ahci_fis_transmit #(
input
cfis_xmit
,
// transmit command (wait for dma_ct_busy == 0)
input
dx_transmit
,
// send FIS header DWORD, (just 0x46), then forward DMA data
// transmit until error, 2048DWords or pDmaXferCnt
input
atapi_xmit
,
// t
ar
smit ATAPI command FIS
input
atapi_xmit
,
// t
ra
smit ATAPI command FIS
output
reg
done
,
...
...
@@ -233,9 +233,12 @@ module ahci_fis_transmit #(
ch_r_r
<=
reg_rdata
[
8
]
;
ch_p_r
<=
reg_rdata
[
7
]
;
ch_w_r
<=
reg_rdata
[
6
]
;
ch_a_r
<=
reg_rdata
[
5
]
;
//
ch_a_r <= reg_rdata[ 5];
ch_cmd_len_r
<=
reg_rdata
[
4
:
0
]
;
end
//ch_a
if
(
hba_rst
||
atapi_xmit
)
ch_a_r
<=
0
;
else
if
(
fetch_chead_stb_r
[
0
])
ch_a_r
<=
reg_rdata
[
5
]
;
if
(
hba_rst
)
pCmdToIssue_r
<=
0
;
else
if
(
chead_done_w
)
pCmdToIssue_r
<=
1
;
...
...
ahci/ahci_fsm.v
View file @
4bf4f348
...
...
@@ -44,8 +44,10 @@ module ahci_fsm
// direct communication with transposrt, link and phy layers
input
phy_ready
,
// goes up after comreset,cominit, align, ...
output
syncesc_send
,
// Send sync escape
input
syncesc_send_done
,
// "SYNC escape until the interface is quiescent..."
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
output
send_R_OK
,
// Should it be originated in this layer SM?
output
send_R_ERR
,
...
...
@@ -153,11 +155,9 @@ module ahci_fsm
// Communication with ahci_fis_receive (some are unused
input
fis_first_vld
,
// fis_first contains valid FIS header, reset by 'get_*'
input
[
7
:
0
]
fis_type
,
// FIS type (low byte in the first FIS DWORD), valid with 'fis_first_vld'
// Receiving FIS
output
set_update_sig
,
// when set, enables get_sig (and resets itself)
input
pUpdateSig
,
// state variable
input
[
7
:
0
]
bist_bits
,
// bits that define built-in self test
output
get_sig
,
// update signature
// Receiving FIS
output
get_dsfis
,
output
get_psfis
,
output
get_rfis
,
...
...
@@ -170,6 +170,13 @@ module ahci_fsm
input
fis_ok
,
// FIS done, checksum OK reset by starting a new get FIS
input
fis_err
,
// FIS done, checksum ERROR reset by starting a new get FIS
input
fis_ferr
,
// FIS done, fatal error - FIS too long
output
set_update_sig
,
// when set, enables get_sig (and resets itself)
input
pUpdateSig
,
// state variable
input
sig_available
,
// device signature available
output
update_sig
,
// update signature
// next commands use register address/data/we for 1 clock cycle - after next to command (commnd - t0, we - t2)
output
update_err_sts
,
// update PxTFD.STS and PxTFD.ERR from the last received regs d2h
output
update_pio
,
// update PxTFD.STS and PxTFD.ERR from pio_* (entry PIO:Update)
...
...
@@ -260,7 +267,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
;
assign
fsm_next
=
(
fsm_preload
||
(
fsm_actions
&&
!
update_busy
&&
!
fsm_act_busy
)
||
fsm_transitions
[
0
])
&&
!
async_pend_r
[
0
]
;
// quiet if received cominit is pending
...
...
@@ -316,6 +323,11 @@ module ahci_fsm
if
(
hba_rst
)
async_pend_r
<=
0
;
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
;
end
/*
...
...
ahci/ahci_top.v
View file @
4bf4f348
...
...
@@ -146,8 +146,10 @@ module ahci_top#(
input
syncesc_recv
,
// These two inputs interrupt transmit
input
xmit_err
,
// Error during sending of a FIS
output
syncesc_send
,
// Send sync escape
input
syncesc_send_done
,
// "SYNC escape until the interface is quiescent..."
input
cominit_got
,
output
set_offline
,
// electrically idle
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
,
...
...
@@ -222,10 +224,6 @@ module ahci_top#(
// fsm <-> ahc_fis_receive
// fsm ->
wire
frcv_first_vld
;
wire
frcv_set_update_sig
;
// when set, enables get_sig (and resets itself)
wire
frcv_pUpdateSig
;
// state variable
wire
frcv_get_sig
;
// update signature
wire
frcv_get_dsfis
;
wire
frcv_get_psfis
;
wire
frcv_get_rfis
;
...
...
@@ -254,6 +252,12 @@ module ahci_top#(
wire
frcv_ok
;
// FIS done, checksum OK reset by starting a new get FIS
wire
frcv_err
;
// FIS done, checksum ERROR reset by starting a new get FIS
wire
frcv_ferr
;
// FIS done, fatal error - FIS too long
wire
frcv_set_update_sig
;
// when set, enables get_sig (and resets itself)
wire
frcv_pUpdateSig
;
// state variable
wire
frcv_sig_available
;
// signature data available
wire
frcv_update_sig
;
// update signature
// fsm <- state variables that are maintained inside 'ahc_fis_receive'
wire
[
7
:
0
]
tfd_sts
;
// Current PxTFD status field (updated after regFIS and SDB - certain fields)
...
...
@@ -419,11 +423,14 @@ module ahci_top#(
.
phy_ready
(
phy_ready
)
,
// input
.
syncesc_send
(
syncesc_send
)
,
// output
.
syncesc_send_done
(
syncesc_send_done
)
,
// input
.
cominit_got
(
cominit_got
)
,
// input
.
set_offline
(
set_offline
)
,
// output
.
x_rdy_collision
(
x_rdy_collision
)
,
// input
.
send_R_OK
(
send_R_OK
)
,
// output
.
send_R_ERR
(
send_R_ERR
)
,
// output
.
update_pending
(
update_regs_pending
)
,
// input
.
update_all
(
update_all_regs
)
,
// output
.
update_busy
(
update_regs_busy
)
,
// input
...
...
@@ -502,9 +509,8 @@ module ahci_top#(
.
fis_first_vld
(
frcv_first_vld
)
,
// input
.
fis_type
(
d2h_data
[
7
:
0
])
,
// input[7:0] FIS type (low byte in the first FIS DWORD), valid with 'fis_first_vld'
.
set_update_sig
(
frcv_set_update_sig
)
,
// output
.
pUpdateSig
(
frcv_pUpdateSig
)
,
// input
.
get_sig
(
frcv_get_sig
)
,
// output
.
bist_bits
(
d2h_data
[
23
:
16
])
,
// bits that define built-in self test
.
get_dsfis
(
frcv_get_dsfis
)
,
// output
.
get_psfis
(
frcv_get_psfis
)
,
// output
.
get_rfis
(
frcv_get_rfis
)
,
// output
...
...
@@ -517,6 +523,12 @@ module ahci_top#(
.
fis_ok
(
frcv_ok
)
,
// input
.
fis_err
(
frcv_err
)
,
// input
.
fis_ferr
(
frcv_ferr
)
,
// input
.
set_update_sig
(
frcv_set_update_sig
)
,
// output
.
pUpdateSig
(
frcv_pUpdateSig
)
,
// input
.
sig_available
(
frcv_sig_available
)
,
// input
.
update_sig
(
frcv_update_sig
)
,
// output
.
update_err_sts
(
frcv_update_err_sts
)
,
// output
.
update_pio
(
frcv_update_pio
)
,
// output
.
update_prdbc
(
frcv_update_prdbc
)
,
// output
...
...
@@ -797,10 +809,7 @@ module ahci_top#(
.
mclk
(
mclk
)
,
// input
.
fis_first_vld
(
frcv_first_vld
)
,
// output reg
.
set_update_sig
(
frcv_set_update_sig
)
,
// input
.
pUpdateSig
(
frcv_pUpdateSig
)
,
// output
.
get_sig
(
frcv_get_sig
)
,
// input
.
get_dsfis
(
frcv_get_dsfis
)
,
// input
.
get_psfis
(
frcv_get_psfis
)
,
// input
.
get_rfis
(
frcv_get_rfis
)
,
// input
...
...
@@ -814,6 +823,11 @@ module ahci_top#(
.
fis_ok
(
frcv_ok
)
,
// output reg
.
fis_err
(
frcv_err
)
,
// output reg
.
fis_ferr
(
frcv_ferr
)
,
// output
.
set_update_sig
(
frcv_set_update_sig
)
,
// input
.
pUpdateSig
(
frcv_pUpdateSig
)
,
// output
.
sig_available
(
frcv_sig_available
)
,
// output reg
.
update_sig
(
frcv_update_sig
)
,
// input
.
update_err_sts
(
frcv_update_err_sts
)
,
// input
.
update_pio
(
frcv_update_pio
)
,
// input update PxTFD.STS and PxTFD.ERR from pio_* (entry PIO:Update)
...
...
helpers/ahci_fsm_sequence.py
View file @
4bf4f348
...
...
@@ -57,9 +57,9 @@ sequence = [{LBL:'POR', ADR: 0x0, ACT: NOP},
{
LBL
:
'P:Init'
,
ACT
:
'PFSM'
},
# pfsm_started HBA init done, port FSM started
{
ACT
:
'PSCI0'
},
# pxci0_clear, reset both (pIssueSlot:=32) and PxCI[0]
{
ACT
:
'CLEAR_BSY_SET_DRQ'
},
#
frcv_
clear_bsy_set_drq
{
ACT
:
'SET_STS_7F'
},
#
frcv_
set_sts_7f
{
ACT
:
'SET_UPDATE_SIG'
},
#
#frcv_
set_update_sig
{
ACT
:
'CLEAR_BSY_SET_DRQ'
},
# clear_bsy_set_drq
{
ACT
:
'SET_STS_7F'
},
# set_sts_7f
{
ACT
:
'SET_UPDATE_SIG'
},
# set_update_sig
{
ACT
:
'XMIT_COMRESET'
},
# Now does it on reset. See if it is possible to transmit COMRESET w/o reset
{
GOTO
:
'P:NotRunning'
},
...
...
@@ -80,9 +80,9 @@ sequence = [{LBL:'POR', ADR: 0x0, ACT: NOP},
# {IF:'PXIE_PCE', GOTO:'P:CominitSetIS'}, # Not needed, interrupt
{
GOTO
:
'P:NotRunning'
},
{
LBL
:
'P:RegFisUpdate'
,
ACT
:
'
NOP'
},
#
{
ACT
:
'
GET_SIG'
},
# get
_sig
# {IF: '
pcmd_fre
', GOTO:'P:RegFisPostToMem'}, # pcmd_fre hardware always copies signature FIS to 'memory' if expected
{
LBL
:
'P:RegFisUpdate'
,
ACT
:
'
GET_RFIS'
},
#get_rfis
{
ACT
:
'
UPDATE_SIG'
},
# update
_sig
# {IF: '
PCMD_FRE
', GOTO:'P:RegFisPostToMem'}, # pcmd_fre hardware always copies signature FIS to 'memory' if expected
{
GOTO
:
'P:NotRunning'
},
{
LBL
:
'P:RegFisPostToMem'
,
ACT
:
'NOP'
},
# Probably not needed, handled at lower level
...
...
@@ -105,10 +105,12 @@ sequence = [{LBL:'POR', ADR: 0x0, ACT: NOP},
{
IF
:
'PCTI_XCZ'
,
GOTO
:
'CFIS:Xmit'
},
# 6. pCmdToIssue && xfer_cntr_zero
{
GOTO
:
'P:Idle'
},
#10. (#7-#9 PM, not implemented)
#P:SelectCmd not implemented, using single slot
{
LBL
:
'P:FetchCmd'
,
ACT
:
'FETCH_CMD'
},
# fetch_cmd (other actions included in ahci_fis_transmit)
{
IF
:
'CTBAA_CTBAP'
,
ACT
:
'CFIS:PrefetchACMD'
},
#1. ch_a && ch_p # Note ch_p may be ignored or transition may be ignored
{
IF
:
'CTBAP'
,
ACT
:
'CFIS:PrefetchPRD'
},
#2. ch_p # Note ch_p may be ignored or transition may be ignored
# PxTFD.STS.BSY must be set before issuing a command (or now if predicted)
{
LBL
:
'P:FetchCmd'
,
ACT
:
'FETCH_CMD'
},
# fetch_cmd (other actions included in ahci_fis_transmit)
#ahci_fis_transmit already processes ch_p. ATAPI data is always preloaded, prd - if ch_p
{
IF
:
'CTBAA_CTBAP'
,
GOTO
:
'CFIS:PrefetchACMD'
},
#1. ch_a && ch_p # Note ch_p may be ignored or transition may be ignored
{
IF
:
'CTBAP'
,
GOTO
:
'CFIS:PrefetchPRD'
},
#2. ch_p # Note ch_p may be ignored or transition may be ignored
{
GOTO
:
'P:Idle'
},
#3. PxTFD.STS.BSY must be set before issuing a command (or now if predicted)
{
LBL
:
'P:StartComm'
,
ACT
:
'SET_STS_7F'
},
# frcv_set_sts_7f
{
ACT
:
'SET_UPDATE_SIG'
},
# #frcv_set_update_sig
{
ACT
:
'XMIT_COMRESET'
},
# Now does it on reset. See if it is possible to transmit COMRESET w/o reset
...
...
@@ -117,14 +119,145 @@ sequence = [{LBL:'POR', ADR: 0x0, ACT: NOP},
#P:PowerOn, P;PwerOff,P:PhyListening - not implemented
#FB:* - Not implemented
#PM:* - Not implemented
{
LBL
:
'PM:Aggr'
,
ACT
:
'NOP'
},
# Just as a placeholder
{
GOTO
:
'P:Idle'
},
#1
{
LBL
:
'NDR:Entry'
,
ACT
:
'NOP'
},
{
IF
:
'FIS_ERR'
,
GOTO
:
'ERR:Non-fatal'
},
# 1. fis_
ok
{
IF
:
'FIS_ERR'
,
GOTO
:
'ERR:Non-fatal'
},
# 1. fis_
err
{
IF
:
'FIS_FERR'
,
GOTO
:
'ERR:Fatal'
},
# 2. fis_ferr
{
GOTO
:
'NDR:Accept'
},
# 3.
{
GOTO
:
'NDR:Accept'
},
# 4.
{
LBL
:
'NDR:IgnoreNR'
,
ACT
:
'FIS_IOGNORE'
},
# get_ignore This one is not in docs, just to empty FIS FIFO
{
GOTO
:
'P:NotRunning'
},
# (was directly from NDR:Accept.4
{
LBL
:
'NDR:IgnoreIdle'
,
ACT
:
'FIS_IOGNORE'
},
# get_ignore This one is not in docs, just to empty FIS FIFO
{
GOTO
:
'P:Idle'
},
# (was directly from NDR:Accept.4
{
LBL
:
'NDR:Accept'
,
ACT
:
'R_OK'
},
# send_R_OK to device
{
IF
:
'NB_ND_D2HR_PIO'
,
GOTO
:
'NDR:IgnoreIdle'
},
# 2 :((FIS == FIS_D2HR) || (FIS == FIS_PIO)) && !PxTBD.STS.BSY & !PxTBD.STS.DRQ
{
IF
:
'NST_D2HR'
,
GOTO
:
'P:RegFisUpdate'
},
# 3 :!ST && (FIS == FIS_D2HR) TODO: does it mean either BSY or DRQ are 1?
{
IF
:
'NPCMD_FRE'
,
GOTO
:
'NDR:IgnoreNR'
},
# 4 !pcmd_fre (docs: goto P:NotRunning, but we need to clear FIFO)
{
IF
:
'D2HR'
,
GOTO
:
'RegFIS:Entry'
},
# 5 FIS == FIS_D2HR
{
IF
:
'SDB'
,
GOTO
:
'SDB:Entry'
},
# 7 (# 6 skipped)
{
IF
:
'DMA_ACT'
,
GOTO
:
'DX:Entry'
},
# 8 FIS == FIS_DMA_ACT
{
IF
:
'DMA_SETUP'
,
GOTO
:
'DmaSet:Entry'
},
# 9 FIS == FIS_DMA_SETUP
{
IF
:
'BIST_ACT_FE'
,
GOTO
:
'BIST:FarEndLoopback'
},
#10 FIS == FIS_BIST_ACT && |bist_bits TODO:get_ignore to read in FIS
{
IF
:
'BIST_ACT'
,
GOTO
:
'BIST:TestOngoing'
},
# 11 FIS == FIS_BIST_ACT && |bist_bits TODO:get_ignore to read in FIS
{
IF
:
'PIO_SETUP'
,
GOTO
:
'PIO:Entry'
},
# 12 FIS == FIS_PIO_SETUP
{
GOTO
:
'UFIS:Entry'
},
# 13 Unknown FIS (else)
#5.3.6. Command Transfer State
{
LBL
:
'CFIS:SyncEscape'
,
ACT
:
'SEND_SYNC_ESC'
},
# syncesc_send, should wait (for syncesc_send_done)
{
ACT
:
'SET_UPDATE_SIG'
},
# set_update_sig
{
GOTO
:
'CFIS:Xmit'
},
# 1
{
LBL
:
'CFIS:Xmit'
,
ACT
:
'SET_BSY'
},
# set_bsy
{
ACT
:
'CFIS_XMIT'
},
# cfis_xmit
{
IF
:
'X_RDY_COLLISION'
,
GOTO
:
'P:Idle'
},
# 2. x_rdy_collision_pend
{
IF
:
'SYNCESC_RECV'
,
GOTO
:
'ERR:SyncEscapeRecv'
},
# 4. syncesc_recv
{
IF
:
'FIS_OK'
,
GOTO
:
'CFIS:SUCCESS'
},
# 5. fis_ok
{
GOTO
:
'ERR:Non-fatal'
},
# 6
{
LBL
:
'CFIS:Success'
,
ACT
:
'CLEAR_CMD_TO_ISSUE'
},
# clearCmdToIssue
{
IF
:
'CTBA_B'
,
GOTO
:
'BIST:TestOngoing'
},
# 1. ch_b
{
IF
:
'CTBA_C'
,
GOTO
:
'CFIS:ClearCI'
},
# 2. ch_c
{
IF
:
'CTBAA_CTBAP'
,
GOTO
:
'CFIS:PrefetchACMD'
},
# 3. ch_a && ch_p # Note ch_p may be ignored or transition may be ignored
{
IF
:
'CTBAP'
,
GOTO
:
'CFIS:PrefetchPRD'
},
# 4. ch_p # Note ch_p may be ignored or transition may be ignored
{
GOTO
:
'P:Idle'
},
# 6.
{
LBL
:
'CFIS:CLearCI'
,
ACT
:
'PSCI0'
},
# pxci0_clear, reset both (pIssueSlot:=32) and PxCI[0]
{
ACT
:
'CLEAR_BSY_DRQ'
},
# clear_bsy_drq
{
GOTO
:
'PM:Aggr'
},
# 1
# As ahci_fis_transmit processes ch_p, GOTO:'CFIS:Prefetch*' can be shortcut to GOTO:'P:Idle'
{
LBL
:
'CFIS:PrefetchACMD'
,
ACT
:
'NOP'
},
# Nothing to do as it is already in memory, fetched together with command
{
IF
:
'CTBAP'
,
GOTO
:
'CFIS:PrefetchPRD'
},
# 1. ch_p Note ch_p may be ignored or transition may be ignored
{
GOTO
:
'P:Idle'
},
# 3.
{
LBL
:
'CFIS:PrefetchPRD'
,
ACT
:
'NOP'
},
# ahci_fis_transmit processes ch_p, no more actions needed
{
GOTO
:
'P:Idle'
},
# 1.
{
LBL
:
'CFIS:PrefetchData'
,
ACT
:
'NOP'
},
# ahci_fis_transmit-> ahci_dma prefetches data if possible
{
GOTO
:
'P:Idle'
},
# 1.
#5.3.7 ATAPI Command Transfer States
{
LBL
:
'ATAPI:Entry'
,
ACT
:
'ATAPI_XMIT'
},
# atapi_xmit, '0->pXferAtapi[pPmpCur]' is done ahci_fis_transmit.
{
IF
:
'TX_ERR'
,
GOTO
:
'ERR:Fatal'
},
# 1. dx_err[1] (reset by new command)
{
GOTO
:
'PIO:Update'
},
# 2.
#5.3.8 D2H Register FIS Receive States
{
LBL
:
'RegFIS:Entry'
,
ACT
:
'GET_RFIS'
},
# get_rfis
{
IF
:
'TFD_STS_ERR'
,
GOTO
:
'ERR:FatalTaskfile'
},
# 1. tfd_sts[0]
{
IF
:
'NB_ND'
,
GOTO
:
'RegFIS:ClearCI'
},
# 2. PxTFD.STS.BSY =’0’ and PxTFD.STS.DRQ =’0’
{
GOTO
:
'RegFIS:UpdateSig'
},
# 3.
{
LBL
:
'RegFIS:ClearCI'
,
ACT
:
'UPDATE_PRDBC'
},
# update_prdbc
{
ACT
:
'PSCI0'
},
# pxci0_clear, reset both (pIssueSlot:=32) and PxCI[0]
{
IF
:
'FIS_I'
,
GOTO
:
'RegFIS:SetIntr'
},
# 2. fis_i
{
GOTO
:
'RegFIS:UpdateSig'
},
# 3.
{
LBL
:
'RegFIS:SetIntr'
,
ACT
:
'SIRQ_DHR'
},
# sirq_DHR
{
GOTO
:
'RegFIS:UpdateSig'
},
# 2. (PxIE/IRQ is handled)
#RegFIS:SetIS, RegFIS:GenIntr are handled by hardware, skipping
{
LBL
:
'RegFIS:UpdateSig'
,
ACT
:
'UPDATE_SIG'
},
# update_sig will only update if pUpdateSig
{
GOTO
:
'PM:Aggr'
},
# 1
#RegFIS:SetSig skipped, done in RegFIS:UpdateSig
#5.3.9 PIO Setup Receive States
{
LBL
:
'PIO:Entry'
,
ACT
:
'GET_PSFIS'
},
# get_psfis, includes all steps 1..9
{
IF
:
'TFD_STS_ERR'
,
GOTO
:
'ERR:FatalTaskfile'
},
# 1. tfd_sts[0]
{
IF
:
'NPD_NCA'
,
GOTO
:
'DX:Entry'
},
# 2. pio_d = 0 && ch_a == 0
{
IF
:
'NPD'
,
GOTO
:
'ATAPI:Entry'
},
# 3. pio_d = 0 , "ch_a == 1" is not needed
{
GOTO
:
'P:Idle'
},
# 4
]
"""
output reg pio_i, // value of "I" field in received PIO Setup FIS
output reg pio_d, // value of "D" field in received PIO Setup FIS
output [7:0] pio_es, // value of PIO E_Status
sirq_DHR
fis_i
update_prdbc, // update PRDBC in registers
output [7:0] tfd_sts, // Current PxTFD status field (updated after regFIS and SDB - certain fields)
// tfd_sts[7] - BSY, tfd_sts[4] - DRQ, tfd_sts[0] - ERR
{LBL:'P:RegFisUpdate', ACT: 'GET_SIG'}, # update_sig
input [ 1:0] dx_err, // bit 0 - syncesc_recv, 1 - xmit_err (valid @ xmit_err and later, reset by new command)
{IF: 'CTBAA_CTBAP', ACT:'CFIS:PrefetchACMD'},#1. ch_a && ch_p # Note ch_p may be ignored or transition may be ignored
{IF: 'CTBAP', ACT:'CFIS:PrefetchPRD'}, #2. ch_p # Note ch_p may be ignored or transition may be ignored
input ch_c, // Clear busy upon R_OK for this FIS
input ch_b, // Built-in self test command
input ch_r, // reset - may need to send SYNC escape before this command
input ch_p, // prefetchable - only used with non-zero PRDTL or ATAPI bit set
input ch_w, // Write: system memory -> device
input ch_a, // ATAPI: 1 means device should send PIO setup FIS for ATAPI command
input [4:0] ch_cfl, // length of the command FIS in DW, 0 means none. 0 and 1 - illegal,
fis_ok
syncesc_recv
x_rdy_collision_pend
input cfis_xmit, // transmit command (wait for dma_ct_busy == 0)
input syncesc_send_done, // "SYNC escape until the interface is quiescent..."
set_update_sig
bist_bits (use get_ignore to read in BIST FIS)
get_ignore
output send_R_OK, // Should it be originated in this layer SM?
output send_R_ERR,
input fis_ok, // FIS done, checksum OK reset by starting a new get FIS
input fis_err, // FIS done, checksum ERROR reset by starting a new get FIS
input fis_ferr, // FIS done, fatal error - FIS too long
...
...
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