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
82906512
Commit
82906512
authored
Jan 16, 2016
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
implemented run-time sequencer for the ahci_fsm, working on the actual sequence
parent
50d15e4c
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
479 additions
and
67 deletions
+479
-67
ahci_ctrl_stat.v
ahci/ahci_ctrl_stat.v
+44
-2
ahci_fis_receive.v
ahci/ahci_fis_receive.v
+24
-10
ahci_fsm.v
ahci/ahci_fsm.v
+159
-20
ahci_top.v
ahci/ahci_top.v
+93
-26
axi_ahci_regs.v
ahci/axi_ahci_regs.v
+18
-2
ahci_fsm_sequence.py
helpers/ahci_fsm_sequence.py
+120
-0
create_ahci_registers.py
helpers/create_ahci_registers.py
+10
-4
ahci_defaults.vh
includes/ahci_defaults.vh
+1
-1
ahci_localparams.vh
includes/ahci_localparams.vh
+9
-1
ahci_types.vh
includes/ahci_types.vh
+1
-1
No files found.
ahci/ahci_ctrl_stat.v
View file @
82906512
...
...
@@ -54,6 +54,11 @@ module ahci_ctrl_stat #(
input
update_pcmd
,
input
update_pci
,
// Next - obsolete?
output
reg
st01_pending
,
// software turned PxCMD.ST from 0 to 1
output
reg
st10_pending
,
// software turned PxCMD.ST from 1 to 0
input
st_pending_reset
,
// reset both st01_pending and st10_pending
// PxCMD
input
pcmd_clear_icc
,
// clear PxCMD.ICC field
input
pcmd_esp
,
// external SATA port (just forward value)
...
...
@@ -61,10 +66,15 @@ module ahci_ctrl_stat #(
input
pcmd_cr_set
,
// command list run set
input
pcmd_cr_reset
,
// command list run reset
input
pcmd_fr
,
// ahci_fis_receive:get_fis_busy - change to HAB set/reset (set, do, reset)
output
pcmd_fre
,
// FIS enable copy to memory
input
pcmd_clear_bsy_drq
,
// == ahci_fis_receive:clear_bsy_drq
output
pcmd_clo
,
//RW1, causes ahci_fis_receive:clear_bsy_drq, that in turn resets this bit
input
pcmd_clear_st
,
// RW clear ST (start) bit
output
pcmd_st
,
// current value
input
pfsm_started
,
// H: FSM done, P: FSM started (enable sensing pcmd_st_cleared)
output
reg
pcmd_st_cleared
,
// ST bit cleared by software; TODO: check not in H:Init (5.3.2.10)
//clear_bsy_drq
// Interrupt inputs
input
sirq_TFE
,
// RWC: Task File Error Status
...
...
@@ -96,7 +106,7 @@ module ahci_ctrl_stat #(
input
serr_ET
,
// RWC: Transient Data Integrity Error (error not recovered by the interface)
input
serr_EM
,
// RWC: Communication between the device and host was lost but re-established
input
serr_EI
,
// RWC: Recovered Data integrity Error
output
serr_diag_X
,
// value of PxSERR.DIAG.X
// SCR0: SStatus
...
...
@@ -119,6 +129,8 @@ module ahci_ctrl_stat #(
output
reg
[
3
:
0
]
sctl_ipm
,
// Interface power management transitions allowed
output
reg
[
3
:
0
]
sctl_spd
,
// Interface maximal speed
output
reg
[
3
:
0
]
sctl_det
,
// Device detection initialization requested
output
reg
sctl_det_changed
,
// Software had written new value to sctl_det
input
sctl_det_reset
,
// clear sctl_det_changed
input
pxci0_clear
,
// PxCI clear
output
pxci0
,
// pxCI current value
...
...
@@ -235,14 +247,22 @@ module ahci_ctrl_stat #(
wire
update_HBA_PORT__PxSERR
=
update_serr
||
update_first
[
3
]
||
update_next
[
3
]
;
wire
update_HBA_PORT__PxCMD
=
update_pcmd
||
update_first
[
4
]
||
update_next
[
4
]
;
wire
update_HBA_PORT__PxCI
=
update_pci
||
update_first
[
5
]
||
update_next
[
5
]
;
reg
pfsm_started_r
;
assign
update_busy
=
(
update_all
&&
(
|
regs_changed
))
||
(
|
updating
[
5
:
1
])
;
assign
update_pending
=
|
regs_changed
;
assign
pcmd_fre
=
|
(
HBA_PORT__PxCMD__FRE__MASK
&
PxCMD_r
)
;
assign
serr_diag_X
=
|
(
HBA_PORT__PxSERR__DIAG__X__MASK
&
PxSERR_r
)
;
localparam
PxIE_MASK
=
HBA_PORT__PxIE__TFEE__MASK
|
// 'h40000000;
HBA_PORT__PxIE__IFE__MASK
|
// 'h8000000;
HBA_PORT__PxIE__INFE__MASK
|
// 'h4000000;
HBA_PORT__PxIE__OFE__MASK
|
// 'h1000000;
HBA_PORT__PxIE__PRCE__MASK
|
// 'h400000;
HBA_PORT__PxIE__PCE__MASK
|
// 'h40;
HBA_PORT__PxIE__DPE__MASK
|
// 'h20
HBA_PORT__PxIE__UFE__MASK
|
// 'h10;
HBA_PORT__PxIE__SDBE__MASK
|
// 'h8;
HBA_PORT__PxIE__DSE__MASK
|
// 'h4;
...
...
@@ -254,6 +274,8 @@ localparam PxIS_MASK = HBA_PORT__PxIS__TFES__MASK | // 'h40000000;
HBA_PORT__PxIS__INFS__MASK
|
// 'h4000000;
HBA_PORT__PxIS__OFS__MASK
|
// 'h1000000;
HBA_PORT__PxIS__PRCS__MASK
|
// 'h400000;
HBA_PORT__PxIS__PCS__MASK
|
// 'h40;
HBA_PORT__PxIS__DPS__MASK
|
// 'h20
HBA_PORT__PxIS__UFS__MASK
|
// 'h10;
HBA_PORT__PxIS__SDBS__MASK
|
// 'h8;
HBA_PORT__PxIS__DSS__MASK
|
// 'h4;
...
...
@@ -393,6 +415,9 @@ localparam PxCMD_MASK = HBA_PORT__PxCMD__ICC__MASK | // 'hf0000000;
always
@
(
posedge
mclk
)
begin
if
(
rst_por
)
{
sctl_ipm
,
sctl_spd
,
sctl_det
}
<=
0
;
else
if
(
swr_HBA_PORT__PxSCTL
)
{
sctl_ipm
,
sctl_spd
,
sctl_det
}
<=
soft_write_data
[
11
:
0
]
;
if
(
rst_por
||
sctl_det_reset
)
sctl_det_changed
<=
0
;
else
if
(
swr_HBA_PORT__PxSCTL
&&
(
soft_write_data
[
3
:
0
]
!=
sctl_det
))
sctl_det_changed
<=
1
;
end
// HBA_PORT__PxSERR register
...
...
@@ -420,6 +445,13 @@ localparam PxCMD_MASK = HBA_PORT__PxCMD__ICC__MASK | // 'hf0000000;
(
HBA_PORT__PxCMD__FRE__MASK
&
PxCMD_r
)
|
// no HBA control
(
pcmd_clear_bsy_drq
?
0
:
(
PxCMD_r
&
HBA_PORT__PxCMD__CLO__MASK
))
|
(
pcmd_clear_st
?
0
:
(
PxCMD_r
&
HBA_PORT__PxCMD__ST__MASK
))
)))
;
if
(
mrst
)
pfsm_started_r
<=
0
;
else
if
(
pfsm_started
)
pfsm_started_r
<=
1
;
if
(
!
pfsm_started_r
)
pcmd_st_cleared
<=
0
;
else
if
(
swr_HBA_PORT__PxCMD
)
pcmd_st_cleared
<=
|
(
HBA_PORT__PxCMD__ST__MASK
&
PxCMD_r
&
~
soft_write_data
)
;
end
// Update AXI registers with the current local data
...
...
@@ -470,6 +502,16 @@ localparam PxCMD_MASK = HBA_PORT__PxCMD__ICC__MASK | // 'hf0000000;
else
if
(
update_all
)
updating
[
5
:
1
]
<=
regs_changed
[
5
:
1
]
&
~
update_first
[
5
:
1
]
;
else
updating
[
5
:
1
]
<=
updating
[
5
:
1
]
&
~
update_next
[
5
:
1
]
;
// detect software setting for PxCMD.ST 0->1 and 1->0
if
(
mrst
)
st01_pending
<=
0
;
else
if
(
swr_HBA_PORT__PxCMD
&&
(
HBA_PORT__PxCMD__ST__MASK
&
soft_write_data
&
~
PxCMD_r
))
st01_pending
<=
1
;
if
(
st_pending_reset
)
st01_pending
<=
0
;
if
(
mrst
)
st10_pending
<=
0
;
else
if
(
swr_HBA_PORT__PxCMD
&&
(
HBA_PORT__PxCMD__ST__MASK
&
~
soft_write_data
&
PxCMD_r
))
st10_pending
<=
1
;
if
(
st_pending_reset
)
st10_pending
<=
0
;
end
endmodule
...
...
ahci/ahci_fis_receive.v
View file @
82906512
...
...
@@ -37,6 +37,8 @@ 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
,
...
...
@@ -55,13 +57,17 @@ module ahci_fis_receive#(
input
update_pio
,
// update PxTFD.STS and PxTFD.ERR from pio_* (entry PIO:Update)
input
update_prdbc
,
// update PRDBC in registers
input
clear_bsy_drq
,
// clear PxTFD.STS.BSY and PxTFD.STS.DRQ, update
input
clear_bsy_set_drq
,
// clear PxTFD.STS.BSY and sets PxTFD.STS.DRQ, update
input
set_bsy
,
// set PxTFD.STS.BSY, update
input
set_sts_7f
,
// set PxTFD.STS = 0x7f, update
input
set_sts_80
,
// set PxTFD.STS = 0x80 (may be combined with set_sts_7f), update
input
clear_xfer_cntr
,
// clear pXferCntr (is it needed as a separate input)?
input
decr_dwc
,
// decrement DMA Xfer counter // need pulse to 'update_prdbc' to write to registers
input
[
11
:
0
]
decr_DXC_dw
,
// decrement value (in DWORDs)
input
pcmd_fre
,
// control bit enables saving FIS to memory (will be ignored for signature)
// TODO: Add writing PRDBC here?
output
reg
pPioXfer
,
// state variable
output
[
7
:
0
]
tfd_sts
,
// Current PxTFD status field (updated after regFIS and SDB - certain fields)
...
...
@@ -181,6 +187,7 @@ 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
// 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
;
...
...
@@ -203,7 +210,7 @@ localparam DATA_TYPE_ERR = 3;
assign
data_in_dwords
=
data_in_dwords_r
;
assign
pio_es
=
pio_es_r
;
assign
pUpdateSig
=
pUpdateSig_r
;
always
@
(
posedge
mclk
)
begin
if
(
hba_rst
||
dma_in_stop
)
dma_in
<=
0
;
else
if
(
dma_in_start
)
dma_in
<=
1
;
...
...
@@ -233,9 +240,13 @@ localparam DATA_TYPE_ERR = 3;
(
{
4
{
get_ufis
}}
&
UFIS32_LENM1
)
|
(
{
4
{
get_data_fis
}}
&
DMAH_LENM1
)
|
(
{
4
{
get_ignore
}}
&
IGNORE_LENM1
)
;
fis_save
<=
!
get_data_fis
&&
!
get_ignore
&&
!
get_sig
;
// 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
)
;
is_data_fis
<=
get_data_fis
;
update_sig
<=
get_sig
?
1
:
0
;
update_sig
<=
((
get_sig
&&
pUpdateSig_r
)
?
1
:
0
)
;
reg_ds
<=
get_dsfis
?
1
:
0
;
reg_ps
<=
get_psfis
?
1
:
0
;
reg_d2h
<=
get_rfis
?
1
:
0
;
...
...
@@ -296,7 +307,8 @@ localparam DATA_TYPE_ERR = 3;
else
if
(
reg_ps
[
0
])
tf_err_sts
<=
{
hba_data_in
[
31
:
24
]
,
hba_data_in
[
23
:
16
]
};
else
if
(
update_pio
)
tf_err_sts
<=
{
pio_err_r
,
pio_es_r
};
else
if
(
reg_sdb
)
tf_err_sts
<=
{
hba_data_in
[
15
:
8
]
,
tf_err_sts
[
7
]
,
hba_data_in
[
6
:
4
]
,
tf_err_sts
[
3
]
,
hba_data_in
[
2
:
0
]
};
else
if
(
clear_bsy_drq
||
set_bsy
)
tf_err_sts
<=
tf_err_sts
&
{
8'hff
,
clear_bsy_drq
,
3'h7
,
clear_bsy_drq
,
3'h7
}
|
{
8'h0
,
set_bsy
,
7'h0
};
else
if
(
clear_bsy_drq
||
set_bsy
||
clear_bsy_set_drq
)
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
;
...
...
@@ -317,7 +329,7 @@ localparam DATA_TYPE_ERR = 3;
if
(
hba_rst
)
pio_es_r
<=
0
;
else
if
(
reg_ps
[
3
])
pio_es_r
<=
hba_data_in
[
31
:
24
]
;
if
(
hba_rst
||
reg_sdb
)
xfer_cntr_r
[
31
:
2
]
<=
0
;
if
(
hba_rst
||
reg_sdb
||
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
,
hba_data_in
[
15
:
2
]
}
+
hba_data_in
[
1
]
;
// round up
else
if
(
decr_dwc
)
xfer_cntr_r
[
31
:
2
]
<=
{
xfer_cntr_r
[
31
:
2
]
}
-
{
18'b0
,
decr_DXC_dw
[
11
:
0
]
};
...
...
@@ -333,6 +345,8 @@ localparam DATA_TYPE_ERR = 3;
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
;
// Maybe it is not needed if the fsm will send this pulse?
...
...
ahci/ahci_fsm.v
View file @
82906512
...
...
@@ -20,40 +20,40 @@
*******************************************************************************/
`timescale
1
ns
/
1
ps
module
ahci_fsm
#(
module
ahci_fsm
/*#(
// parameter PREFETCH_ALWAYS = 0,
parameter READ_REG_LATENCY = 2, // 0 if reg_rdata is available with reg_re/reg_addr, 2 with re/regen
// parameter READ_CT_LATENCY = 1, // 0 if ct_rdata is available with reg_re/reg_addr, 2 with re/regen
parameter ADDRESS_BITS = 10 // number of memory address bits - now fixed. Low half - RO/RW/RWC,RW1 (2-cycle write), 2-nd just RW (single-cycle)
)(
) */
(
input
hba_rst
,
// @posedge mclk
input
mclk
,
// for command/status
input
was_hba_rst
,
// last reset was hba reset (not counting system reset)
input
was_port_rst
,
// last reset was port reset
/*
// notification from axi_ahci_regs that software has written data to register
input [ADDRESS_BITS-1:0] soft_write_addr, // register address written by software
input [31:0] soft_write_data, // register data written (after applying wstb and type (RO, RW, RWC, RW1)
input soft_write_en, // write enable for data write
// input soft_arst, // reset SATA PHY not relying on SATA clock
// R/W access to AXI/AHCI registers, shared with ahci_fis_receive and ahci_fis_transmit modules
output [ADDRESS_BITS-1:0] regs_addr,
output regs_we,
// output [3:0] regs_wstb, Needed?
output [1:0] regs_re, // [0] - re, [1] - regen
output [31:0] regs_din,
input [31:0] regs_dout,
*/
// Writing FSM program memory
input
aclk
,
input
arst
,
input
[
17
:
0
]
pgm_ad
,
// @aclk, address/data to program the AHCI FSM
input
pgm_wa
,
// @aclk, address strobe to program the AHCI FSM
input
pgm_wd
,
// @aclk, data strobe to program the 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
cominit_got
,
// asynchronously jumps to P:Cominit state
output
set_offline
,
// electrically idle
output
send_R_OK
,
// Should it be originated in this layer SM?
output
send_R_ERR
,
// Other signals....
// Communication with ahci_ctrl_stat (some are not needed)
// update register inputs (will write to register memory current value of the corresponding register)
output
pfsm_started
,
// H: FSM doene, P: FSM started (enable sensing pcmd_st_cleared)
// update register inputs (will write to register memory current value of the corresponding register)
input
update_pending
,
output
update_all
,
...
...
@@ -64,6 +64,9 @@ module ahci_fsm #(
output
update_serr
,
output
update_pcmd
,
output
update_pci
,
input
st01_pending
,
// software turned PxCMD.ST from 0 to 1
input
st10_pending
,
// software turned PxCMD.ST from 1 to 0
output
st_pending_reset
,
// reset both st01_pending and st10_pending
// PxCMD
output
pcmd_clear_icc
,
// clear PxCMD.ICC field
...
...
@@ -76,6 +79,8 @@ module ahci_fsm #(
input
pcmd_clo
,
//RW1, causes ahci_fis_receive:clear_bsy_drq, that in turn resets this bit
output
pcmd_clear_st
,
// RW clear ST (start) bit
input
pcmd_st
,
// current value
input
pcmd_st_cleared
,
// ST bit cleared by software;
//clear_bsy_drq
// Interrupt inputs
output
sirq_TFE
,
// RWC: Task File Error Status
...
...
@@ -107,6 +112,7 @@ module ahci_fsm #(
output
serr_ET
,
// RWC: Transient Data Integrity Error (error not recovered by the interface)
output
serr_EM
,
// RWC: Communication between the device and host was lost but re-established
output
serr_EI
,
// RWC: Recovered Data integrity Error
input
serr_diag_X
,
// value of PxSERR.DIAG.X
...
...
@@ -131,6 +137,8 @@ module ahci_fsm #(
input
[
3
:
0
]
sctl_ipm
,
// Interface power management transitions allowed
input
[
3
:
0
]
sctl_spd
,
// Interface maximal speed
input
[
3
:
0
]
sctl_det
,
// Device detection initialization requested
input
sctl_det_changed
,
// Software had written new value to sctl_det
output
sctl_det_reset
,
// clear sctl_det_changed
output
pxci0_clear
,
// PxCI clear
input
pxci0
,
// pxCI current value
...
...
@@ -145,6 +153,9 @@ module ahci_fsm #(
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
output
get_sig
,
// update signature
output
get_dsfis
,
output
get_psfis
,
...
...
@@ -164,11 +175,16 @@ module ahci_fsm #(
output
update_prdbc
,
// update PRDBC in registers
output
clear_bsy_drq
,
// clear PxTFD.STS.BSY and PxTFD.STS.DRQ, update
output
clear_bsy_set_drq
,
// clear PxTFD.STS.BSY and sets PxTFD.STS.DRQ, update
output
set_bsy
,
// set PxTFD.STS.BSY, update
output
set_sts_7f
,
// set PxTFD.STS = 0x7f, update
output
set_sts_80
,
// set PxTFD.STS = 0x80 (may be combined with set_sts_7f), update
output
clear_xfer_cntr
,
// clear pXferCntr (is it needed as a separate input)?
output
decr_dwc
,
// decrement DMA Xfer counter // need pulse to 'update_prdbc' to write to registers
output
[
11
:
0
]
decr_DXC_dw
,
// decrement value (in DWORDs)
// output [11:0] decr_DXC_dw, // decrement value (in DWORDs)
input
pxcmd_fre
,
// control bit enables saving FIS to memory
input
pPioXfer
,
// state variable
input
[
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
...
...
@@ -192,8 +208,8 @@ module ahci_fsm #(
output
dx_transmit
,
// send FIS header DWORD, (just 0x46), then forward DMA data
// transmit until error, 2048DWords or pDmaXferCnt
output
atapi_xmit
,
// tarsmit ATAPI command FIS
input
done
,
input
busy
,
input
xmit_
done
,
input
xmit_
busy
,
output
clearCmdToIssue
,
// From CFIS:SUCCESS
input
pCmdToIssue
,
// AHCI port variable
...
...
@@ -215,8 +231,131 @@ module ahci_fsm #(
)
;
`include
"includes/ahci_localparams.vh"
// @SuppressThisWarning VEditor : Unused localparams
reg
[
10
:
0
]
pgm_waddr
;
// wire pgm_ren;
// wire pgm_regen;
wire
cond_met_w
;
// calculated from signals and program conditions decoder
reg
[
10
:
0
]
pgm_jump_addr
;
reg
[
10
:
0
]
pgm_addr
;
wire
[
17
:
0
]
pgm_data
;
reg
was_rst
;
// reg jump_r;
reg
[
2
:
0
]
fsm_jump
;
wire
fsm_next
;
reg
fsm_actions
;
// processing actions
reg
fsm_act_busy
;
reg
[
1
:
0
]
fsm_transitions
;
// processing transitions
reg
fsm_preload
;
// read first sequence data (2 cycles for regen)
wire
[
6
:
0
]
precond_w
=
pgm_data
[
17
:
11
]
;
// select what to use - cond_met_w valis after precond_w, same time as conditions
reg
[
6
:
0
]
conditions
;
wire
pre_jump_w
=
(
|
async_pend_r
)
?
async_ackn
:
(
cond_met_w
&
fsm_transitions
[
1
])
;
wire
fsm_act_done
=
get_fis_done
||
xmit_done
;
wire
fsm_wait_act_w
=
pgm_data
[
16
]
;
// this action requires waiting for done
wire
fsm_last_act_w
=
pgm_data
[
17
]
;
wire
fsm_pre_act_w
=
fsm_actions
&&
fsm_next
;
// use it as CS for generated actions (registered)
reg
[
1
:
0
]
async_pend_r
;
// waiting to process cominit_got
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
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
// Writing to the FSM program memory
always
@
(
posedge
aclk
)
begin
if
(
arst
)
pgm_waddr
<=
0
;
else
if
(
pgm_wa
)
pgm_waddr
<=
pgm_ad
[
10
:
0
]
;
else
if
(
pgm_wd
)
pgm_waddr
<=
pgm_waddr
+
1
;
end
// Reset addresses - later use generated
localparam
LABEL_POR
=
11'h000
;
localparam
LABEL_HBA_RST
=
11'h002
;
localparam
LABEL_PORT_RST
=
11'h004
;
localparam
LABEL_COMINIT
=
11'h006
;
localparam
LABEL_ST_CLEARED
=
11'h008
;
always
@
(
posedge
mclk
)
begin
if
(
hba_rst
)
pgm_jump_addr
<=
(
was_hba_rst
||
was_port_rst
)
?
(
was_hba_rst
?
LABEL_HBA_RST
:
LABEL_PORT_RST
)
:
LABEL_POR
;
else
if
(
async_pend_r
[
1
])
pgm_jump_addr
<=
async_from_st
?
LABEL_ST_CLEARED
:
LABEL_COMINIT
;
else
if
(
fsm_transitions
[
0
]
&&
(
!
cond_met_w
||
!
fsm_transitions
[
1
]))
pgm_jump_addr
<=
pgm_data
[
10
:
0
]
;
was_rst
<=
hba_rst
;
fsm_jump
<=
{
fsm_jump
[
1
:
0
]
,
pre_jump_w
|
(
was_rst
&
~
hba_rst
)
};
if
(
fsm_jump
[
0
])
pgm_addr
<=
pgm_jump_addr
;
else
if
(
fsm_next
)
pgm_addr
<=
pgm_addr
+
1
;
if
(
hba_rst
)
conditions
<=
0
;
if
(
fsm_transitions
[
0
])
conditions
<=
precond_w
;
if
(
hba_rst
)
fsm_actions
<=
0
;
else
if
(
fsm_jump
[
2
])
fsm_actions
<=
1
;
else
if
(
fsm_last_act_w
&&
fsm_next
)
fsm_actions
<=
0
;
if
(
hba_rst
||
pre_jump_w
)
fsm_transitions
<=
0
;
else
if
(
fsm_last_act_w
&&
fsm_actions
&&
fsm_next
)
fsm_transitions
<=
1
;
else
fsm_transitions
<=
{
fsm_transitions
[
0
]
,
fsm_transitions
[
0
]
};
if
(
hba_rst
)
fsm_preload
<=
0
;
else
fsm_preload
<=
|
fsm_jump
[
1
:
0
]
;
if
(
hba_rst
)
fsm_act_busy
<=
0
;
else
if
(
fsm_pre_act_w
)
fsm_act_busy
<=
fsm_wait_act_w
;
else
if
(
fsm_act_done
)
fsm_act_busy
<=
0
;
if
(
pcmd_st_cleared
)
async_from_st
<=
1
;
else
if
(
asynq_rq
)
async_from_st
<=
0
;
if
(
hba_rst
)
async_pend_r
<=
0
;
else
async_pend_r
<=
{
async_pend_r
[
0
]
,
asynq_rq
|
(
async_pend_r
[
0
]
&
~
async_ackn
)
};
end
/*
sequence = [{LBL:'POR', ADR: 0x0, ACT: NOP},
{ GOTO:'H:Init'},
{LBL:'HBA_RST', ADR: 0x2, ACT: NOP},
{ GOTO:'H:Init'},
{LBL:'PORT_RST', ADR: 0x4, ACT: NOP},
{ GOTO:'H:Init'},
{LBL:'COMINIT', ADR: 0x6, ACT: NOP},
{ GOTO:'P:Cominit'},
*/
ramp_var_w_var_r
#(
.
REGISTERS
(
1
)
,
.
LOG2WIDTH_WR
(
4
)
,
.
LOG2WIDTH_RD
(
4
)
)
fsm_pgm_mem_i
(
.
rclk
(
mclk
)
,
// input
.
raddr
(
pgm_addr
)
,
// input[10:0]
.
ren
(
fsm_next
)
,
// input
.
regen
(
fsm_next
)
,
// input
.
data_out
(
pgm_data
)
,
// output[17:0]
.
wclk
(
aclk
)
,
// input
.
waddr
(
pgm_waddr
)
,
// input[10:0]
.
we
(
pgm_wd
)
,
// input
.
web
(
8'hff
)
,
// input[7:0]
.
data_in
(
pgm_ad
)
// input[17:0]
)
;
/*
output update_all,
input update_busy, // valid same cycle as update_all
Notes:
Implement sync esc request/ackn in TL (available in LL)
*/
...
...
ahci/ahci_top.v
View file @
82906512
...
...
@@ -146,6 +146,11 @@ 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
cominit_got
,
output
set_offline
,
// electrically idle
output
send_R_OK
,
// Should it be originated in this layer SM?
output
send_R_ERR
,
output
irq
// CPU interrupt request
...
...
@@ -191,7 +196,11 @@ module ahci_top#(
wire
dma_cmd_start
;
// input
wire
dma_prd_start
;
// input
wire
dma_cmd_abort
;
// input
// Use some of the custom registers in the adderss space?
// Use some of the custom registers in the address space?
wire
[
17
:
0
]
fsm_pgm_ad
;
// @aclk, address/data to program the AHCI FSM
wire
fsm_pgm_wa
;
// @aclk, address strobe to program the AHCI FSM
wire
fsm_pgm_wd
;
// @aclk, data strobe to program the AHCI FSM
wire
[
3
:
0
]
axi_wr_cache_mode
;
// input[3:0]
wire
[
3
:
0
]
axi_rd_cache_mode
;
// input[3:0]
...
...
@@ -213,6 +222,9 @@ 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
;
...
...
@@ -228,10 +240,13 @@ module ahci_top#(
wire
frcv_update_prdbc
;
// update PRDBC in registers
wire
frcv_clear_bsy_drq
;
// clear PxTFD.STS.BSY and PxTFD.STS.DRQ, update
wire
frcv_clear_bsy_set_drq
;
// clear PxTFD.STS.BSY and sets PxTFD.STS.DRQ, update
wire
frcv_set_bsy
;
// set PxTFD.STS.BSY, update
wire
frcv_set_sts_7f
;
// set PxTFD.STS = 0x7f, update
wire
frcv_set_sts_80
;
// set PxTFD.STS = 0x80 (may be combined with set_sts_7f), update
wire
frcv_decr_dwc
;
// decrement DMA Xfer counter // need pulse to 'update_prdbc' to write to registers
wire
frcv_clear_xfer_cntr
;
// Clear pXferCntr to 0
// fsm <-
wire
frcv_busy
;
// busy processing FIS
...
...
@@ -294,6 +309,11 @@ module ahci_top#(
wire
update_all_regs
;
wire
update_regs_busy
;
// valid same cycle as update_all_regs
wire
st01_pending
;
// software turned PxCMD.ST from 0 to 1
wire
st10_pending
;
// software turned PxCMD.ST from 1 to 0
wire
st_pending_reset
;
// reset both st01_pending and st10_pending
// these following individual signals may be unneded - use update_all_regs -> update_regs_busy
wire
update_GHC__IS
;
wire
update_HBA_PORT__PxIS
;
...
...
@@ -309,10 +329,13 @@ module ahci_top#(
wire
pcmd_cr_set
;
// command list run set
wire
pcmd_cr_reset
;
// command list run reset
wire
pcmd_fr
;
// ahci_fis_receive:get_fis_busy
wire
pcmd_fre
;
// FIS enable copy to memory
wire
pcmd_clear_bsy_drq
;
// == ahci_fis_receive:clear_bsy_drq
wire
pcmd_clo
;
//RW1, causes ahci_fis_receive:clear_bsy_drq, that in turn resets this bit
wire
pcmd_clear_st
;
// RW clear ST (start) bit
wire
pcmd_st
;
// current value
wire
pfsm_started
;
// H: FSM done, P: FSM started (enable sensing pcmd_st_cleared)
wire
pcmd_st_cleared
;
// bit was cleared by software
//clear_bsy_drq
// Interrupt inputs
wire
sirq_TFE
;
// RWC: Task File Error Status
...
...
@@ -344,6 +367,7 @@ module ahci_top#(
wire
serr_ET
;
// RWC: Transient Data Integrity Error (error not recovered by the interface)
wire
serr_EM
;
// RWC: Communication between the device and host was lost but re-established
wire
serr_EI
;
// RWC: Recovered Data integrity Error
wire
serr_diag_X
;
// value of PxSERR.DIAG.X
...
...
@@ -367,25 +391,38 @@ module ahci_top#(
wire
[
3
:
0
]
sctl_ipm
;
// Interface power management transitions allowed
wire
[
3
:
0
]
sctl_spd
;
// Interface maximal speed
wire
[
3
:
0
]
sctl_det
;
// Device detection initialization requested
wire
sctl_det_changed
;
// Software had written new value to sctl_det
wire
sctl_det_reset
;
// clear sctl_det_changed
wire
pxci0_clear
;
// PxCI clear
wire
pxci0
;
// pxCI current value
ahci_fsm
#(
.
READ_REG_LATENCY
(
2
)
,
.
ADDRESS_BITS
(
10
)
)
ahci_fsm_i
(
ahci_fsm
// #(
// .READ_REG_LATENCY(2),
// .ADDRESS_BITS(10)
// )
ahci_fsm_i
(
.
hba_rst
(
mrst
)
,
// input
.
mclk
(
mclk
)
,
// input
.
was_hba_rst
(
was_hba_rst
)
,
// input
.
was_port_rst
(
was_port_rst
)
,
// input
.
aclk
(
aclk
)
,
// input
.
arst
(
arst
)
,
// input
.
pgm_ad
(
fsm_pgm_ad
)
,
// input[17:0]
.
pgm_wa
(
fsm_pgm_wa
)
,
// input
.
pgm_wd
(
fsm_pgm_wd
)
,
// input
.
phy_ready
(
phy_ready
)
,
// input
.
syncesc_send
(
syncesc_send
)
,
// output
.
cominit_got
(
cominit_got
)
,
// input
.
set_offline
(
set_offline
)
,
// output
.
update_pending
(
update_regs_pending
)
,
// 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
.
update_gis
(
update_GHC__IS
)
,
// output
...
...
@@ -394,7 +431,9 @@ module ahci_top#(
.
update_serr
(
update_HBA_PORT__PxSERR
)
,
// output
.
update_pcmd
(
update_HBA_PORT__PxCMD
)
,
// output
.
update_pci
(
update_HBA_PORT__PxCI
)
,
// output
.
st01_pending
(
st01_pending
)
,
// input
.
st10_pending
(
st10_pending
)
,
// input
.
st_pending_reset
(
st_pending_reset
)
,
// output
.
pcmd_clear_icc
(
pcmd_clear_icc
)
,
// output
.
pcmd_esp
(
pcmd_esp
)
,
// output
.
pcmd_cr
(
pcmd_cr
)
,
// input
...
...
@@ -405,6 +444,8 @@ module ahci_top#(
.
pcmd_clo
(
pcmd_clo
)
,
// input
.
pcmd_clear_st
(
pcmd_clear_st
)
,
// output
.
pcmd_st
(
pcmd_st
)
,
// input
.
pfsm_started
(
pfsm_started
)
,
// output
.
pcmd_st_cleared
(
pcmd_st_cleared
)
,
// input
.
sirq_TFE
(
sirq_TFE
)
,
// output
.
sirq_IF
(
sirq_IF
)
,
// output
.
sirq_INF
(
sirq_INF
)
,
// output
...
...
@@ -429,6 +470,7 @@ module ahci_top#(
.
serr_ET
(
serr_ET
)
,
// output
.
serr_EM
(
serr_EM
)
,
// output
.
serr_EI
(
serr_EI
)
,
// output
.
serr_diag_X
(
serr_diag_X
)
,
// input
.
ssts_ipm_dnp
(
ssts_ipm_dnp
)
,
// output
.
ssts_ipm_active
(
ssts_ipm_active
)
,
// output
.
ssts_ipm_part
(
ssts_ipm_part
)
,
// output
...
...
@@ -445,10 +487,11 @@ module ahci_top#(
.
sctl_ipm
(
sctl_ipm
)
,
// input[3:0]
.
sctl_spd
(
sctl_spd
)
,
// input[3:0]
.
sctl_det
(
sctl_det
)
,
// input[3:0]
.
sctl_det_changed
(
sctl_det_changed
)
,
// input
.
sctl_det_reset
(
sctl_det_reset
)
,
// output
.
pxci0_clear
(
pxci0_clear
)
,
// output
.
pxci0
(
pxci0
)
,
// input
.
dma_prd_done
(
dma_prd_done
)
,
// input
.
dma_prd_irq
(
dma_prd_irq
)
,
// input
.
dma_cmd_busy
(
dma_cmd_busy
)
,
// input
...
...
@@ -456,6 +499,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
.
get_dsfis
(
frcv_get_dsfis
)
,
// output
.
get_psfis
(
frcv_get_psfis
)
,
// output
...
...
@@ -473,11 +518,15 @@ module ahci_top#(
.
update_pio
(
frcv_update_pio
)
,
// output
.
update_prdbc
(
frcv_update_prdbc
)
,
// output
.
clear_bsy_drq
(
frcv_clear_bsy_drq
)
,
// output
.
clear_bsy_set_drq
(
frcv_clear_bsy_set_drq
)
,
//output
.
set_bsy
(
frcv_set_bsy
)
,
// output
.
set_sts_7f
(
frcv_set_sts_7f
)
,
// output
.
set_sts_80
(
frcv_set_sts_80
)
,
// output
.
decr_dwc
(
frcv_decr_dwc
)
,
// output
.
decr_DXC_dw
(
data_out_dwords
)
,
// output[11:2] **** Probably not needed
.
clear_xfer_cntr
(
frcv_clear_xfer_cntr
)
,
//output Clear pXferCntr
.
decr_dwc
(
frcv_decr_dwc
)
,
// output increment pXferCntr after transmit by data transmitted)
// .decr_DXC_dw (data_out_dwords), // output[11:2] **** Probably not needed
.
pxcmd_fre
(
pcmd_fre
)
,
// input
.
pPioXfer
(
pPioXfer
)
,
// input
.
tfd_sts
(
tfd_sts
)
,
// input[7:0]
...
...
@@ -496,8 +545,8 @@ module ahci_top#(
.
cfis_xmit
(
fsnd_cfis_xmit
)
,
// output
.
dx_transmit
(
fsnd_dx_transmit
)
,
// output
.
atapi_xmit
(
fsnd_atapi_xmit
)
,
// output
.
done
(
fsnd_done
)
,
// input
.
busy
(
fsnd_busy
)
,
// input
.
xmit_done
(
fsnd_done
)
,
// input
.
xmit_busy
(
fsnd_busy
)
,
// input
.
clearCmdToIssue
(
fsnd_clearCmdToIssue
)
,
// output // From CFIS:SUCCESS
.
pCmdToIssue
(
fsnd_pCmdToIssue
)
,
// input
.
dx_err
(
fsnd_dx_err
)
,
// input[1:0]
...
...
@@ -509,7 +558,7 @@ module ahci_top#(
.
ch_w
(
fsnd_ch_w
)
,
// input
.
ch_a
(
fsnd_ch_a
)
,
// input
.
ch_cfl
(
fsnd_ch_cfl
)
,
// input[4:0]
.
dwords_sent
(
data_out_dwords
)
// input[11:0]
.
dwords_sent
(
data_out_dwords
)
// input[11:0]
????
)
;
...
...
@@ -561,6 +610,9 @@ module ahci_top#(
.
hba_re
(
regs_re
)
,
// input[1:0]
.
hba_din
(
regs_din
)
,
// input[31:0]
.
hba_dout
(
regs_dout
)
,
// output[31:0]
.
pgm_ad
(
fsm_pgm_ad
)
,
// output[17:0] reg
.
pgm_wa
(
fsm_pgm_wa
)
,
// output reg
.
pgm_wd
(
fsm_pgm_wd
)
,
// output reg
.
afi_wcache
(
axi_wr_cache_mode
)
,
// output[3:0] reg
.
afi_rcache
(
axi_rd_cache_mode
)
,
// output[3:0] reg
.
afi_cache_set
(
set_axi_cache_mode
)
,
// output
...
...
@@ -586,7 +638,9 @@ module ahci_top#(
.
update_pending
(
update_regs_pending
)
,
// output
.
update_all
(
update_all_regs
)
,
// input
.
update_busy
(
update_regs_busy
)
,
// output
// input update_pending,
.
st01_pending
(
st01_pending
)
,
// output reg
.
st10_pending
(
st10_pending
)
,
// output reg
.
st_pending_reset
(
st_pending_reset
)
,
// input
.
update_gis
(
update_GHC__IS
)
,
// input
.
update_pis
(
update_HBA_PORT__PxIS
)
,
// input
...
...
@@ -600,10 +654,13 @@ module ahci_top#(
.
pcmd_cr_set
(
pcmd_cr_set
)
,
// input
.
pcmd_cr_reset
(
pcmd_cr_reset
)
,
// input
.
pcmd_fr
(
pcmd_fr
)
,
// input
.
pcmd_fre
(
pcmd_fre
)
,
// output
.
pcmd_clear_bsy_drq
(
pcmd_clear_bsy_drq
)
,
// input
.
pcmd_clo
(
pcmd_clo
)
,
// output
.
pcmd_clear_st
(
pcmd_clear_st
)
,
// input
.
pcmd_st
(
pcmd_st
)
,
// output
.
pfsm_started
(
pfsm_started
)
,
// input
.
pcmd_st_cleared
(
pcmd_st_cleared
)
,
// output reg
.
sirq_TFE
(
sirq_TFE
)
,
// input
.
sirq_IF
(
sirq_IF
)
,
// input
.
sirq_INF
(
sirq_INF
)
,
// input
...
...
@@ -628,6 +685,7 @@ module ahci_top#(
.
serr_ET
(
serr_ET
)
,
// input
.
serr_EM
(
serr_EM
)
,
// input
.
serr_EI
(
serr_EI
)
,
// input
.
serr_diag_X
(
serr_diag_X
)
,
// output
.
ssts_ipm_dnp
(
ssts_ipm_dnp
)
,
// input
.
ssts_ipm_active
(
ssts_ipm_active
)
,
// input
.
ssts_ipm_part
(
ssts_ipm_part
)
,
// input
...
...
@@ -644,6 +702,8 @@ module ahci_top#(
.
sctl_ipm
(
sctl_ipm
)
,
// output[3:0] reg
.
sctl_spd
(
sctl_spd
)
,
// output[3:0] reg
.
sctl_det
(
sctl_det
)
,
// output[3:0] reg
.
sctl_det_changed
(
sctl_det_changed
)
,
// output reg
.
sctl_det_reset
(
sctl_det_reset
)
,
// input
.
pxci0_clear
(
pxci0_clear
)
,
// input
.
pxci0
(
pxci0
)
,
// output
.
irq
(
irq
)
// output reg
...
...
@@ -733,6 +793,8 @@ 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
...
...
@@ -754,11 +816,16 @@ module ahci_top#(
.
update_prdbc
(
frcv_update_prdbc
)
,
// input
.
clear_bsy_drq
(
frcv_clear_bsy_drq
)
,
// input
.
clear_bsy_set_drq
(
frcv_clear_bsy_set_drq
)
,
// input
.
set_bsy
(
frcv_set_bsy
)
,
// input
.
set_sts_7f
(
frcv_set_sts_7f
)
,
// input
.
set_sts_80
(
frcv_set_sts_80
)
,
// input
.
clear_xfer_cntr
(
frcv_clear_xfer_cntr
)
,
// input Clear pXferCntr
.
decr_dwc
(
frcv_decr_dwc
)
,
// input
.
decr_DXC_dw
(
data_out_dwords
)
,
// input[11:2]
.
pcmd_fre
(
pcmd_fre
)
,
// input
.
pPioXfer
(
pPioXfer
)
,
// output reg
.
tfd_sts
(
tfd_sts
)
,
// output[7:0]
...
...
ahci/axi_ahci_regs.v
View file @
82906512
...
...
@@ -100,6 +100,13 @@ module axi_ahci_regs#(
input
[
31
:
0
]
hba_din
,
output
[
31
:
0
]
hba_dout
,
// Program FSM memory
output
reg
[
17
:
0
]
pgm_ad
,
// @aclk, address/data to program the AHCI FSM
output
reg
pgm_wa
,
// @aclk, address strobe to program the AHCI FSM
output
reg
pgm_wd
,
// @aclk, data strobe to program the AHCI FSM
// other control signals
output
reg
[
3
:
0
]
afi_wcache
,
output
reg
[
3
:
0
]
afi_rcache
,
...
...
@@ -160,6 +167,8 @@ module axi_ahci_regs#(
wire
high_sel
=
bram_waddr_r
[
ADDRESS_BITS
-
1
]
;
// high addresses - use single-cycle writes without read-modify-write
wire
afi_cache_set_w
=
bram_wen_r
&&
!
high_sel
&&
(
bram_addr
==
HBA_PORT__AFI_CACHE__WR_CM__ADDR
)
;
wire
pgm_fsm_set_w
=
bram_wen_r
&&
!
high_sel
&&
(
bram_addr
==
HBA_PORT__PGM_AHCI_SM__PGM_AD__ADDR
)
;
wire
pgm_fsm_and_w
=
|
(
ahci_regs_di
&
HBA_PORT__PGM_AHCI_SM__AnD__MASK
)
;
wire
set_hba_rst
=
bram_wen_r
&&
!
high_sel
&&
(
bram_addr
==
GHC__GHC__HR__ADDR
)
&&
(
ahci_regs_di
&
GHC__GHC__HR__MASK
)
;
wire
set_port_rst
=
bram_wen_r
&&
!
high_sel
&&
(
bram_addr
==
HBA_PORT__PxSCTL__DET__ADDR
)
&&
...
...
@@ -228,7 +237,6 @@ module axi_ahci_regs#(
if
(
arst
||
set_hba_rst
)
was_port_rst_aclk
<=
0
;
else
if
(
port_rst_on
)
was_port_rst_aclk
<=
1
;
end
always
@
(
hba_clk
)
begin
...
...
@@ -243,6 +251,14 @@ module axi_ahci_regs#(
else
if
(
afi_cache_set_w
)
{
afi_wcache
,
afi_rcache
}
<=
ahci_regs_di
[
7
:
0
]
;
end
always
@
(
posedge
aclk
)
begin
if
(
arst
)
{
pgm_wa
,
pgm_wd
}
<=
0
;
else
{
pgm_wa
,
pgm_wd
}
<=
{
2
{
pgm_fsm_set_w
}}
&
{
pgm_fsm_and_w
,
~
pgm_fsm_and_w
};
if
(
pgm_fsm_set_w
)
pgm_ad
<=
ahci_regs_di
[
17
:
0
]
;
end
/*
Will generate async reset on both HBA reset(for some time) and port reset (until released)
until it is more clear about GTX reset options. Such reset will be applied to both PLL and GTX,
...
...
helpers/ahci_fsm_sequence.py
0 → 100644
View file @
82906512
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from
__future__
import
print_function
from
__future__
import
division
# Copyright (C) 2016, Elphel.inc.
# Helper module create AHCI registers type/default data
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
__author__
=
"Andrey Filippov"
__copyright__
=
"Copyright 2016, Elphel, Inc."
__license__
=
"GPL"
__version__
=
"3.0+"
__maintainer__
=
"Andrey Filippov"
__email__
=
"andrey@elphel.com"
__status__
=
"Development"
import
sys
LBL
=
"Label"
ACT
=
"Action"
IF
=
"If"
GOTO
=
"Goto"
ADR
=
"Address"
NOP
=
"NOP"
sequence
=
[{
LBL
:
'POR'
,
ADR
:
0x0
,
ACT
:
NOP
},
{
GOTO
:
'H:Init'
},
{
LBL
:
'HBA_RST'
,
ADR
:
0x2
,
ACT
:
NOP
},
{
GOTO
:
'H:Init'
},
{
LBL
:
'PORT_RST'
,
ADR
:
0x4
,
ACT
:
NOP
},
{
GOTO
:
'H:Init'
},
{
LBL
:
'COMINIT'
,
ADR
:
0x6
,
ACT
:
NOP
},
{
GOTO
:
'P:Cominit'
},
{
LBL
:
'ST_CLEARED'
,
ADR
:
0x6
,
ACT
:
NOP
},
# TODO: make sure this jump is not from P:Init
{
GOTO
:
'P:StartBitCleared'
},
{
LBL
:
'H:Init'
,
ACT
:
NOP
},
{
GOTO
:
'H:WaitForAhciEnable'
},
{
LBL
:
'H:WaitForAhciEnable'
,
ACT
:
NOP
},
{
GOTO
:
'H:Idle'
},
# GHC.AE is always on
{
LBL
:
'H:Idle'
,
ACT
:
NOP
},
{
GOTO
:
'P:Init'
},
#All required actions for H* are done in hardware, just go to port initialization
{
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
:
'XMIT_COMRESET'
},
# Now does it on reset. See if it is possible to transmit COMRESET w/o reset
{
GOTO
:
'P:NotRunning'
},
{
LBL
:
'P:NotRunning'
,
ACT
:
'NOP'
},
# 'PSCI0'}, # pxci0_clear, - should not be here as it updates soft registers?
{
IF
:
'SCTL_DET_CHANGED_TO_4'
,
GOTO
:
'P:Offline'
},
#4
{
IF
:
'SCTL_DET_CHANGED_TO_1'
,
GOTO
:
'P:StartComm'
},
#5
# Transition 8. PxCMD.FRE written to ‘1’ from a ‘0’ and previously processed Register FIS is in receive FIFO and PxSERR.DIAG.X = ‘0’
# can not be implemented - it is too late, FIS is already gone. So as we do not move FIS receive area, there is no sense to disable FIS,
# and for the signature we'll always assume FRE is on
{
IF
:
'ST_NB_ND'
,
GOTO
:
'P:Idle'
},
#12 : PxCMD.ST & !PxTBD.STS.BSY & !PxTBD.STS.DRQ
{
IF
:
'FR_D2HR'
,
GOTO
:
'NDR:Entry'
},
#13 fis_first_vld & fis_type == 0x34 (D2H Register)
{
GOTO
:
'P:NotRunning'
},
#14
{
LBL
:
'P:Cominit'
,
ACT
:
'NOP'
},
# got here asynchronously from COMINIT label
{
ACT
:
'SET_STS_80'
},
# frcv_set_sts_80 (Not clear 0xff or 0x80 should be here?)
{
ACT
:
'PXSSTS_DET_1'
},
# ssts_det_dnp, // device detected, but phy communication not established
{
ACT
:
'PXSERR_DIAG_X'
},
# sirq_PC, // RO: Port Connect Change Status (pulse to set)
# {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
{
GOTO
:
'P:NotRunning'
},
{
LBL
:
'P:RegFisPostToMem'
,
ACT
:
'NOP'
},
# Probably not needed, handled at lower level
{
GOTO
:
'P:NotRunning'
},
{
LBL
:
'P:Offline'
,
ACT
:
'SET_OFFLINE'
},
# set_offline
{
GOTO
:
'P:NotRunning'
},
{
LBL
:
'P:StartBitCleared'
,
ACT
:
'PXCI0_CLEAR'
},
# pxci0_clear
{
ACT
:
'DMA_ABORT'
},
# dma_cmd_abort (should eventually clear PxCMD.CR)?
{
ACT
:
'PCMD_CR_CLEAR'
},
# pcmd_cr_reset
{
ACT
:
'XFER_CNTR_CLEAR'
},
# clear_xfer_cntr
{
LBL
:
'P:Idle'
,
ACT
:
'PCMD_CR_SET'
},
# pcmd_cr_set
]
"""
pcmd_cr_set, // command list run set
clear_xfer_cntr
pcmd_cr_reset
frcv_clear_xfer_cntr
dma_cmd_abort
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'
serr_diag_X ==0 , fis_first_vld,
(pIssueSlot==32) is the same as (pxci0 == 0), use pxci0_clear (pIssueSlot:=32)
localparam LABEL_POR = 11'h0;
localparam LABEL_HBA_RST = 11'h10;
localparam LABEL_PORT_RST = 11'h20;
"""
\ No newline at end of file
helpers/create_ahci_registers.py
View file @
82906512
...
...
@@ -423,15 +423,21 @@ src=[{gN:"PCI_Header", gS: PCIHEAD, gE:PCIHEAD+0x3f, gD:" PCI header emulation w
{
fN
:
"MDAT"
,
fS
:
10
,
fE
:
14
,
fT
:
RW
,
fC
:
0
,
fD
:
"Minimum Device Sleep Assertion Time"
},
{
fN
:
"DETO"
,
fS
:
2
,
fE
:
9
,
fT
:
RW
,
fC
:
0
,
fD
:
"Device Sleep Exit Timeout"
},
{
fN
:
"DSP"
,
fS
:
1
,
fT
:
RO
,
fC
:
0
,
fD
:
"Device Sleep Present"
},
{
fN
:
"ADSE"
,
fS
:
1
,
fT
:
RO
,
fC
:
0
,
fD
:
"Aggressive Device Sleep Enable"
}
{
fN
:
"ADSE"
,
fS
:
0
,
fT
:
RO
,
fC
:
0
,
fD
:
"Aggressive Device Sleep Enable"
}
]},
{
rN
:
"AFI_CACHE"
,
rS
:
0x70
,
rE
:
0x73
,
rD
:
"Port x Vendor Specific"
,
rC
:
# 0x48..0x6f - reserved
{
rN
:
"AFI_CACHE"
,
rS
:
0x70
,
rE
:
0x73
,
rD
:
"Port x Vendor Specific, program AXI cache modes"
,
rC
:
[{
fS
:
8
,
fE
:
31
,
fT
:
RO
,
fC
:
0
,
fD
:
"Reserved"
},
{
fN
:
"WR_CM"
,
fS
:
4
,
fE
:
7
,
fT
:
RW
,
fC
:
3
,
fD
:
"SAXIHP write channel cache mode "
},
{
fN
:
"RD_CM"
,
fS
:
0
,
fE
:
3
,
fT
:
RW
,
fC
:
3
,
fD
:
"SAXIHP read channel cache mode "
},
]},
# 0x48..0x6f - reserved
{
rN
:
"PxVS"
,
rS
:
0x74
,
rE
:
0x7f
,
rD
:
"Other Port x Vendor Specific"
,
rC
:
{
rN
:
"PGM_AHCI_SM"
,
rS
:
0x74
,
rE
:
0x77
,
rD
:
"Port x Vendor Specific, AHCI state machine"
,
rC
:
[{
fS
:
25
,
fE
:
31
,
fT
:
RO
,
fC
:
0
,
fD
:
"Reserved"
},
{
fN
:
"AnD"
,
fS
:
24
,
fT
:
RW
,
fC
:
0
,
fD
:
"Address/not data for programming AHCI state machine"
},
{
fS
:
18
,
fE
:
23
,
fT
:
RO
,
fC
:
0
,
fD
:
"Reserved"
},
{
fN
:
"PGM_AD"
,
fS
:
0
,
fE
:
17
,
fT
:
RW
,
fC
:
3
,
fD
:
"Program address/data for programming AHCI state machine"
},
]},
{
rN
:
"PxVS"
,
rS
:
0x78
,
rE
:
0x7f
,
rD
:
"Other Port x Vendor Specific"
,
rC
:
[{
fT
:
RW
,
fC
:
0
,
fD
:
"Vendor-specific data - 96 bits"
}
]},
...
...
includes/ahci_defaults.vh
View file @
82906512
, .INIT_00 (256'h0000000000000000000000000001030100000001000000008000000000240020)
, .INIT_08 (256'h000000000024000600000000000000000000000080000C000000000080000800)
, .INIT_09 (256'h000000000000000000000000000000000000000000000000FFFFFFFF00000000)
, .INIT_0B (256'h00000000000000000000000
0
0000003300000000000000000000000000000000)
, .INIT_0B (256'h00000000000000000000000
3
0000003300000000000000000000000000000000)
, .INIT_0C (256'h000000000000000000000000000000000000000001010001001000000001FFFE)
, .INIT_0D (256'h000001000000000000000040000000000001FFFE000000008000000000000000)
, .INIT_0E (256'h0000000000000000000000000000000000000000000000000000000040000001)
includes/ahci_localparams.vh
View file @
82906512
...
...
@@ -776,7 +776,7 @@
localparam HBA_PORT__PxDEVSLP__DSP__DFLT = 'h0;
// RO: Aggressive Device Sleep Enable
localparam HBA_PORT__PxDEVSLP__ADSE__ADDR = 'h51;
localparam HBA_PORT__PxDEVSLP__ADSE__MASK = 'h
2
;
localparam HBA_PORT__PxDEVSLP__ADSE__MASK = 'h
1
;
localparam HBA_PORT__PxDEVSLP__ADSE__DFLT = 'h0;
// RW: SAXIHP write channel cache mode
localparam HBA_PORT__AFI_CACHE__WR_CM__ADDR = 'h5c;
...
...
@@ -786,4 +786,12 @@
localparam HBA_PORT__AFI_CACHE__RD_CM__ADDR = 'h5c;
localparam HBA_PORT__AFI_CACHE__RD_CM__MASK = 'hf;
localparam HBA_PORT__AFI_CACHE__RD_CM__DFLT = 'h3;
// RW: Address/not data for programming AHCI state machine
localparam HBA_PORT__PGM_AHCI_SM__AnD__ADDR = 'h5d;
localparam HBA_PORT__PGM_AHCI_SM__AnD__MASK = 'h1000000;
localparam HBA_PORT__PGM_AHCI_SM__AnD__DFLT = 'h0;
// RW: Program address/data for programming AHCI state machine
localparam HBA_PORT__PGM_AHCI_SM__PGM_AD__ADDR = 'h5d;
localparam HBA_PORT__PGM_AHCI_SM__PGM_AD__MASK = 'h3ffff;
localparam HBA_PORT__PGM_AHCI_SM__PGM_AD__DFLT = 'h3;
includes/ahci_types.vh
View file @
82906512
...
...
@@ -4,7 +4,7 @@
, .INIT_12 (256'h0000000000550000000000000000000000000000000000000000000000000000)
, .INIT_13 (256'h00000000AAAAAAAAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF002AAAAA00AA000A)
, .INIT_14 (256'h000000000000000000000000000000000001555555555550000000000055000D)
, .INIT_17 (256'h55555555555555555555555555555555
5555555
5555555550000000000005555)
, .INIT_17 (256'h55555555555555555555555555555555
0001000
5555555550000000000005555)
, .INIT_18 (256'h00000000000055550000000000000000AA820000001000140000000000000000)
, .INIT_1B (256'h0000000000005555000000000000000000000000000000000000000000000000)
, .INIT_1C (256'h0000000000000000000000000000000000000000800100050000000000000000)
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