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
Expand all
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
This diff is collapsed.
Click to expand it.
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