# SATA controller on Artix 7

Problem background: My ultimate aim is to implement a SATA host controller on an Artix 7 FPGA. Having said that I am first focusing on the physical layer. Through my research I have found and read through open source IP located here: http://www.ecs.umass.edu/ece/tessier/rcg/virtex4-sata/sata_core.html

The IP described above is for an older family of FPGA devices and hence cannot be easily imported into the newer Vivado environment.

My question: Would it be better to start the physical layer from scratch using the 7-series transceiver wizard OR should I try to migrate bit by bit the old protocol to be used on the newer device?

Important notes:

• Rocket IO transceivers are not supported in Vivado
• The new device does not have a SATA output port itself like the ML405 board used for the open source core
• From the product guide it seems like the 7-series transceiver wizard handles all the SATA physical layer things such as OOB, 8b/10b, comma detection etc. BUT there is no formal documentation or example design I can locate about SATA.

I wrote a SATA controller for a Spartan 6 and Virtex 6. It was not easy and it needs some work to be usable.

That said, I would suggest using Coregen to implement the Physical layer.

I found that there are quite a few registers that are not documented within the gigabit transceivers of the different FPGA generations. It's much better to follow the wizard. If I were going to start out on an Artix7 I would select the following:

Line Rate/RefClk Selection

Encoding and Clocking

Comma Alignment and Equalization

PCIe, SATA, PRBS

CB and CC Sequence

Most of the selections are the default SATA 2 configurations but I chose to use 32-bit data bus.

Side note

Although you didn't ask I think this should be said:

While developing I wrote a simulated phy layer. It worked out really well because it both sped up development and I could disable the scrambler whenever I needed to.

Creating a simulated phy layer shouldn't be that bad. It really boils down to something like this interface:

module sata_phy_layer (

input               rst,            //reset
input               clk,

input               platform_ready,   //the underlying physical platform is
output              platform_error,

output  [31:0]      tx_dout,
output              tx_is_k,
output              tx_comm_reset,
output              tx_comm_wake,
output              tx_elec_idle,
input               tx_oob_complete,

input   [31:0]      rx_din,
input   [3:0]       rx_is_k,  //I should have kept the rx/tx_is_k consistent 4 or 1 :/
input               rx_elec_idle,
input               rx_byte_is_aligned,

input               comm_init_detect,
input               comm_wake_detect,