ahci_top.v 83.1 KB
Newer Older
1 2 3 4 5 6 7
/*!
 * <b>Module:</b>ahci_top
 * @file ahci_top.v
 * @date 2016-01-09  
 * @author Andrey Filippov     
 *
 * @brief Top module of the AHCI implementation
8
 * 
9 10 11 12
 * @copyright Copyright (c) 2016 Elphel, Inc .
 *
 * <b>License:</b>
 *
13 14 15 16 17 18 19 20 21 22 23 24
 * ahci_top.v 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.
 *
 *  ahci_top.v 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/> .
25
 */
26 27 28
`timescale 1ns/1ps

module  ahci_top#(
Andrey Filippov's avatar
Andrey Filippov committed
29 30
    parameter PREFETCH_ALWAYS =       0,
    parameter READ_REG_LATENCY =      2, // 0 if  reg_rdata is available with reg_re/reg_addr, 2 with re/regen
Andrey Filippov's avatar
Andrey Filippov committed
31 32
//    parameter READ_CT_LATENCY =       1, // 0 if  ct_rdata is available with reg_re/reg_addr, 2 with re/regen
    parameter READ_CT_LATENCY =       2, // 0 if  ct_rdata is available with reg_re/reg_addr, 2 with re/regen
Andrey Filippov's avatar
Andrey Filippov committed
33 34
    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)
    parameter HBA_RESET_BITS =        9, // duration of HBA reset in aclk periods (9: ~10usec)
35 36 37
    parameter RESET_TO_FIRST_ACCESS = 1, // keep port reset until first R/W any register by software
    parameter FREQ_METER_WIDTH =     12
    
38 39
)(
    input             aclk,    // clock - should be buffered
40 41
    input             arst,    // @aclk sync reset, active high
    input             mclk,    // SATA system clock (current 75MHz for SATA2)
42
    input             mrst,    // reset in mclk clock domain (after SATA PLL is on)
43
    // async reset for SATA (mrst will be response to it)
44
    output            hba_arst,          // hba async reset (currently does ~ the same as port reset)
Andrey Filippov's avatar
Andrey Filippov committed
45 46
    output            port_arst,         // port0 async set by software (does not include arst)
    output            port_arst_any,     // port0 async set by software and by arst
47 48
    input             hclk,    // AXI HP interface clock for 64-bit DMA (current - 150MHz
    input             hrst,    // reset in hclk clock domain
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
// MAXIGP1   
// AXI Write Address
    input      [31:0] awaddr,  // AWADDR[31:0], input
    input             awvalid, // AWVALID, input
    output            awready, // AWREADY, output
    input      [11:0] awid,    // AWID[11:0], input
    input      [ 3:0] awlen,   // AWLEN[3:0], input
    input      [ 1:0] awsize,  // AWSIZE[1:0], input
    input      [ 1:0] awburst, // AWBURST[1:0], input
// AXI PS Master GP0: Write Data
    input      [31:0] wdata,   // WDATA[31:0], input
    input             wvalid,  // WVALID, input
    output            wready,  // WREADY, output
    input      [11:0] wid,     // WID[11:0], input
    input             wlast,   // WLAST, input
    input      [ 3:0] wstb,    // WSTRB[3:0], input
65
// AXI PS Master GP0: Write response
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
    output            bvalid,  // BVALID, output
    input             bready,  // BREADY, input
    output     [11:0] bid,     // BID[11:0], output
    output     [ 1:0] bresp,    // BRESP[1:0], output
// AXI Read Address   
    input      [31:0] araddr,  // ARADDR[31:0], input 
    input             arvalid, // ARVALID, input
    output            arready, // ARREADY, output
    input      [11:0] arid,    // ARID[11:0], input
    input      [ 3:0] arlen,   // ARLEN[3:0], input
    input      [ 1:0] arsize,  // ARSIZE[1:0], input
    input      [ 1:0] arburst, // ARBURST[1:0], input
// AXI Read Data
    output     [31:0] rdata,   // RDATA[31:0], output
    output            rvalid,  // RVALID, output
    input             rready,  // RREADY, input
    output     [11:0] rid,     // RID[11:0], output
    output            rlast,   // RLAST, output
    output     [ 1:0] rresp,   // RRESP
// SAXIHP3    
    // axi_hp signals write channel
    // write address
    output     [31:0] afi_awaddr,
    output            afi_awvalid,
    input             afi_awready, // @SuppressThisWarning VEditor unused - used FIF0 level
    output     [ 5:0] afi_awid,
    output     [ 1:0] afi_awlock,
    output     [ 3:0] afi_awcache,
    output     [ 2:0] afi_awprot,
    output     [ 3:0] afi_awlen,
    output     [ 1:0] afi_awsize,
    output     [ 1:0] afi_awburst,
    output     [ 3:0] afi_awqos,
    // write data
    output     [63:0] afi_wdata,
    output            afi_wvalid,
Andrey Filippov's avatar
Andrey Filippov committed
102
    input             afi_wready,  // @ SuppressThisWarning VEditor unused - used FIF0 level
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
    output     [ 5:0] afi_wid,
    output            afi_wlast,
    output     [ 7:0] afi_wstrb,
    // write response
    input             afi_bvalid,   // @SuppressThisWarning VEditor unused
    output            afi_bready,
    input      [ 5:0] afi_bid,      // @SuppressThisWarning VEditor unused
    input      [ 1:0] afi_bresp,    // @SuppressThisWarning VEditor unused
    // PL extra (non-AXI) signals
    input      [ 7:0] afi_wcount,
    input      [ 5:0] afi_wacount,
    output            afi_wrissuecap1en,
    // AXI_HP signals - read channel
    // read address
    output     [31:0] afi_araddr,
    output               afi_arvalid,
    input                afi_arready,  // @SuppressThisWarning VEditor unused - used FIF0 level
    output     [ 5:0] afi_arid,
    output     [ 1:0] afi_arlock,
    output     [ 3:0] afi_arcache,
    output     [ 2:0] afi_arprot,
    output     [ 3:0] afi_arlen,
    output     [ 1:0] afi_arsize,
    output     [ 1:0] afi_arburst,
    output     [ 3:0] afi_arqos,
    // read data
    input      [63:0] afi_rdata,
    input             afi_rvalid,
    output            afi_rready,
    input      [ 5:0] afi_rid,     // @SuppressThisWarning VEditor unused
    input             afi_rlast,   // @SuppressThisWarning VEditor unused
    input      [ 1:0] afi_rresp,   // @SuppressThisWarning VEditor unused
    // PL extra (non-AXI) signals
    input      [ 7:0] afi_rcount,
    input      [ 2:0] afi_racount,
138 139 140 141 142 143 144 145 146 147 148 149 150
    output            afi_rdissuecap1en,
// Data/type FIFO, host -> device   
    // Data System memory or FIS -> device
    output      [31:0] h2d_data,     // 32-bit data from the system memory to HBA (dma data)
    output      [ 1:0] h2d_type,     // 0 - data, 1 - FIS head, 2 - FIS END (make FIS_Last?)
    output             h2d_valid,    // output register full
    input              h2d_ready,     // send FIFO has room for data (>= 8? dwords)
 
// Data/type FIFO, device -> host
    input       [31:0] d2h_data,         // FIFO output data
    input       [ 1:0] d2h_type,    // 0 - data, 1 - FIS head, 2 - R_OK, 3 - R_ERR
    input              d2h_valid,  // Data available from the transport layer in FIFO                
    input              d2h_many,    // Multiple DWORDs available from the transport layer in FIFO           
151 152 153
    output             d2h_ready,   // This module or DMA consumes DWORD
    
    // communication with transport/link/phys layers
154 155
//    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
156
    input              xmit_ok,      // FIS transmission acknowledged OK
157
    input              xmit_err,     // Error during sending of a FIS
158
    input              syncesc_recv, // These two inputs interrupt transmit
159
    output             pcmd_st_cleared, // bit was cleared by software    
160
    output             syncesc_send,  // Send sync escape
161
    input              syncesc_send_done, // "SYNC escape until the interface is quiescent..."
162
    output             comreset_send,     // Not possible yet?
163 164
    input              cominit_got,
    output             set_offline, // electrically idle
165
    input              x_rdy_collision, // X_RDY/X_RDY collision on interface 
166
    
167 168
    output             send_R_OK,    // Should it be originated in this layer SM?
    output             send_R_ERR,
169 170 171 172 173 174 175 176 177 178 179
    
    // additional errors from SATA layers (single-clock pulses):
    input              serr_DT,   // RWC: Transport state transition error
    input              serr_DS,   // RWC: Link sequence error
    input              serr_DH,   // RWC: Handshake Error (i.e. Device got CRC error)
    input              serr_DC,   // RWC: CRC error in Link layer
    input              serr_DB,   // RWC: 10B to 8B decode error
    input              serr_DW,   // RWC: COMMWAKE signal was detected
    input              serr_DI,   // RWC: PHY Internal Error
                                  // sirq_PRC,
                                  // sirq_IF || // sirq_INF  
180
    input              serr_EE,   // RWC: Internal error (such as elastic buffer overflow or primitive mis-alignment)
181 182 183 184 185 186 187 188 189 190
    input              serr_EP,   // RWC: Protocol Error - a violation of SATA protocol detected
    input              serr_EC,   // RWC: Persistent Communication or Data Integrity Error
    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
    // additional control signals for SATA layers
    output       [3:0] sctl_ipm,          // Interface power management transitions allowed
    output       [3:0] sctl_spd,          // Interface maximal speed
    
    
191

192
    output             irq, // CPU interrupt request
193 194
    input              debug_link_send_data, // @posedge sata_clk - last symbol was data output (to count sent out)
    input              debug_link_dmatp,     // link received DMATp from device
195 196 197 198 199 200 201 202 203 204
    
`ifdef USE_DATASCOPE
// Datascope interface (write to memory that can be software-read)
    input                    datascope1_clk,
    input [ADDRESS_BITS-1:0] datascope1_waddr,      
    input                    datascope1_we,
    input             [31:0] datascope1_di,
`endif    
    
    
Andrey Filippov's avatar
Andrey Filippov committed
205 206 207 208 209 210 211 212
`ifdef USE_DRP
    output                    drp_en, // @aclk strobes drp_ad
    output                    drp_we,
    output             [14:0] drp_addr,       
    output             [15:0] drp_di,
    input                     drp_rdy,
    input              [15:0] drp_do, 
`endif    
213
    input  [FREQ_METER_WIDTH - 1:0] xclk_period,      // relative (to 2*clk) xclk period
214 215
    input       [31:0] debug_in_phy,
    input       [31:0] debug_in_link
216
    
217 218
    
);
219 220 221 222 223 224 225 226
`ifdef USE_DATASCOPE
// Datascope interface (write to memory that can be software-read)
   wire                     datascope_clk;
   wire  [ADDRESS_BITS-1:0] datascope_waddr;      
   wire                     datascope_we;
   wire              [31:0] datascope_di;
`endif    

227 228 229 230
// axi_ahci_regs signals:
// 1. Notification of data written @ hba_clk
    wire [ADDRESS_BITS-1:0] soft_write_addr;  // register address written by software
    wire             [31:0] soft_write_data;  // register data written (after applying wstb and type (RO, RW, RWC, RW1)
231 232 233
    wire                    soft_write_en;    // write enable for data write
//    wire                    hba_arst;       // hba async reset (currently does ~ the same as port reset)
//    wire                    port_arst;      // port0 async reset by software
234
// 2. HBA R/W registers, use hba clock
235
//    wire                    hba_rst;
236 237 238
    wire                    regs_we_acs;
//    wire              [1:0] regs_re_fsm;
    wire             [31:0] regs_din_from_acs; // from fsm
239 240
    wire                    regs_we_freceive;
    wire              [1:0] regs_re_ftransmit; // [0] - re, [1] - regen
241
    wire [ADDRESS_BITS-1:0] regs_saddr; // read/write adderss from ahci_fsm
242 243
    wire [ADDRESS_BITS-1:0] regs_waddr;
    wire [ADDRESS_BITS-1:0] regs_raddr;
244
    wire             [31:0] regs_din_from_freceive;
245
    wire             [31:0] regs_dout;
246 247 248 249 250 251

    reg                     en_port;
    wire              [1:0] regs_re = en_port ?  regs_re_ftransmit : 2'b0; // [0] - re, [1] - regen
    wire                    regs_we = en_port ? ( regs_we_freceive | regs_we_acs) : 1'b0;


Andrey Filippov's avatar
Andrey Filippov committed
252 253
    wire [ADDRESS_BITS-1:0] regs_addr = ({ADDRESS_BITS{regs_we_freceive}} & regs_waddr) |
                                        ({ADDRESS_BITS{regs_re_ftransmit[0]}} & regs_raddr) |
254
                                        ({ADDRESS_BITS{regs_we_acs}} & regs_saddr);
255
                                        
256 257 258 259 260 261

/*
    wire [ADDRESS_BITS-1:0] regs_addr = ({ADDRESS_BITS{en_port & regs_we_freceive}} & regs_waddr) |
                                        ({ADDRESS_BITS{en_port & regs_re_ftransmit[0]}} & regs_raddr) |
                                        ({ADDRESS_BITS{en_port & regs_we_acs}} & regs_saddr);
*/                                        
262
    wire             [31:0] regs_din =  ({32{regs_we_freceive}} & regs_din_from_freceive) |
263 264
                                        ({32{regs_we_acs}} &      regs_din_from_acs);
//    wire              [1:0] regs_re = regs_re_ftransmit | regs_re_fsm; // [0] - re, [1] - regen
265
    
266
    
267 268
//---------------------    

269 270
//    wire             [31:7] ctba; // input[31:7] 
    wire                    ctba_ld; // input
271 272
    wire             [15:0] prdtl; // input[15:0]
     
273 274 275
    wire                    dev_wr; // input
    wire                    dma_cmd_start; // input
    wire                    dma_prd_start; // input
276
    wire                    dma_cmd_abort_xmit; // input
277
    wire                    dma_cmd_abort_fsm;  // abort from FSM (also from ahci_fis_transmit)
278
        
279 280 281 282 283
// 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
    
284
    
285 286
    wire             [ 3:0] axi_wr_cache_mode; // input[3:0] 
    wire             [ 3:0] axi_rd_cache_mode; // input[3:0] 
287
    wire                    set_axi_cache_mode; // input (both axi_wr_cache_mode and axi_rd_cache_mode)
288 289 290 291
    wire                    dma_ct_busy; // output reg 
    wire             [ 4:0] dma_ct_addr; // input[4:0] 
    wire             [ 1:0] dma_ct_re; // input
    wire             [31:0] dma_ct_data; // output[31:0] reg 
292
///    wire                    dma_prd_done; // output (finished next prd)
293 294
    wire                    dma_prd_irq_clear; // reset pending prd_irq
    wire                    dma_prd_irq_pend;  // prd interrupt pending. This is just a condition for irq - actual will be generated after FIS OK
295
    wire                    dma_cmd_busy; // output reg (DMA engine is processing PRDs)
296
    wire                    dma_cmd_done; // output (last PRD is over)
297 298 299 300 301

    wire                    dma_abort_busy;
    wire                    dma_abort_done;
    wire                    axi_mismatch;
    
302 303 304
    wire             [31:0] dma_dout;    // output[31:0] 
    wire                    dma_dav; // output
    wire                    dma_re;      // input
305 306
    wire                    last_h2d_data;// when active and no new data for 2 clocks - that was the last one
    
307 308
    wire                    dma_in_ready; // output
    wire                    dma_we;      // input
309 310 311
    wire                    dma_extra_din;    // all DRDs are transferred to memory, but FIFO has some data. Valid when transfer is stopped
    
    
312
// ---------------------------------------
313 314 315
    // fsm <-> ahc_fis_receive
    // fsm ->
    wire                    frcv_first_vld;
316 317 318 319
    // To debug/recover - 
    wire                    frcv_first_invalid; // Some data available from FIFO, but not FIS head
    wire                    frcv_first_flush;   // Skip FIFO data until empty or FIS head
    
320 321 322 323 324 325 326 327 328 329
    wire                    frcv_get_dsfis;
    wire                    frcv_get_psfis;
    wire                    frcv_get_rfis;
    wire                    frcv_get_sdbfis;
    wire                    frcv_get_ufis;
    wire                    frcv_get_data_fis;
    wire                    frcv_get_ignore;    // ignore whatever FIS (use for DMA activate too?)
    // short commands:
    // next commands use register address/data/we for 1 clock cycle - after next to command (commnd - t0, we - t2)
    wire                    frcv_update_err_sts;// update PxTFD.STS and PxTFD.ERR from the last received regs d2h
330 331
    wire                    frcv_update_pio;    // update PxTFD.STS and PxTFD.ERR from pio_* (entry PIO:Update)
    
332 333
    wire                    frcv_update_prdbc;  // update PRDBC in registers
    wire                    frcv_clear_bsy_drq; // clear PxTFD.STS.BSY and PxTFD.STS.DRQ, update
334 335
    wire                    frcv_clear_bsy_set_drq; // clear PxTFD.STS.BSY and sets PxTFD.STS.DRQ, update
    
336 337 338
    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
339 340
    wire                    frcv_decr_dwcr;      // decrement DMA Xfer counter after read // need pulse to 'update_prdbc' to write to registers
    wire                    frcv_decr_dwcw;      // decrement DMA Xfer counter after write // need pulse to 'update_prdbc' to write to registers
341
    wire                    frcv_clear_xfer_cntr; // Clear pXferCntr to 0
342 343 344 345 346 347 348
    
    // fsm <-
    wire                    frcv_busy;          // busy processing FIS 
    wire                    frcv_done;          // done processing FIS (see fis_ok, fis_err, fis_ferr)
    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
349 350
    wire                    frcv_extra;         // DMA all transferred, but some data is still in left. . Does not deny frcv_ok
    
351
    wire                    frcv_set_update_sig; // when set, enables get_sig (and resets itself)
352 353
///    wire                    frcv_pUpdateSig;     // state variable
///    wire                    frcv_sig_available;  // signature data available
354 355
    wire                    frcv_update_sig;        // update signature

356 357 358
    
    // 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)
Andrey Filippov's avatar
Andrey Filippov committed
359
                                           // tfd_sts[7] - BSY, tfd_sts[3] - DRQ, tfd_sts[0] - ERR
360
//    wire              [7:0] tfd_err;       // Current PxTFD error field (updated after regFIS and SDB)
361
    wire                    fis_i;         // value of "I" field in received regsD2H or SDB FIS
362
///    wire                    sdb_n;         // value of "N" field in received SDB FIS 
363
    wire                    dma_a;         // value of "A" field in received DMA Setup FIS 
364
///    wire                    dma_d;         // value of "D" field in received DMA Setup FIS
365 366
    wire                    pio_i;         // value of "I" field in received PIO Setup FIS
    wire                    pio_d;         // value of "D" field in received PIO Setup FIS
367
///    wire              [7:0] pio_es;        // value of PIO E_Status
368
    wire                    pPioXfer;
369
///    wire                    sactive0;      // bit 0 of sActive DWORD received in SDB FIS
370 371
    // Using even word count (will be rounded up), partial DWORD (last) will be handled by PRD length if needed
    
372
    wire             [31:2] xfer_cntr; 
373
    wire                    xfer_cntr_zero; 
374
                                             
375
///    wire             [11:0] data_in_dwords;  // number of DWORDs received in data FIS (can be updated internally). Is it needed?
376 377 378

    // fsm <-> ahc_fis_transmit
    // Command pulses to execute states fsm -> ahc_fis_transmit
379
    wire                    fsnd_fetch_cmd;    // Enter p:FetchCmd, fetch command header (from the register memory, prefetch command FIS)
380 381
                                               // 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)
382 383 384
    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
385 386
    // responses fsm <- ahc_fis_transmit
    wire                    fsnd_done;
387
///    wire                    fsnd_busy;
388 389 390 391
    // Short action pulses fsm -> ahc_fis_transmit
    wire                    fsnd_clearCmdToIssue; // From CFIS:SUCCESS 
    // State variables fsm <- ahc_fis_transmit 
    wire                    fsnd_pCmdToIssue; // AHCI port variable
392
    wire             [ 2:0] fsnd_dx_err;       // bit 0 - syncesc_recv, 1 - R_ERR (was xmit_err)  2 - X-RDY/X_RDY collision (valid @ xmit_err and later, reset by new command)
393 394 395 396 397 398
    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
    wire                    fsnd_ch_p;        // prefetchable - only used with non-zero PRDTL or ATAPI bit set
    wire                    fsnd_ch_w;        // Write: system memory -> device
    wire                    fsnd_ch_a;        // ATAPI: 1 means device should send PIO setup FIS for ATAPI command
399
///    wire              [4:0] fsnd_ch_cfl;      // length of the command FIS in DW, 0 means none. 0 and 1 - illegal, ... Maybe not needed outside ahc_fis_transmit
400 401 402

    wire             [11:0] data_out_dwords; // number of DWORDs sent in data FIS

403 404
    wire                    was_hba_rst; 
    wire                    was_port_rst; 
405

406
    // signals between ahci_fsm and ahci_ctrl_stat
407
///    wire                          update_regs_pending;
408 409
    wire                          update_all_regs;
    wire                          update_regs_busy; // valid same cycle as update_all_regs
410

411 412 413
///    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
414

415
    
416
    // these following individual signals may be unneded - use update_all_regs -> update_regs_busy
417 418 419 420 421 422
//    wire                          update_GHC__IS;
//    wire                          update_HBA_PORT__PxIS;
//    wire                          update_HBA_PORT__PxSSTS;
//    wire                          update_HBA_PORT__PxSERR;
//    wire                          update_HBA_PORT__PxCMD;
//    wire                          update_HBA_PORT__PxCI;
423 424

// PxCMD
425 426 427
//    wire                          pcmd_clear_icc; // clear PxCMD.ICC field
    wire                          pcmd_esp = 1'b0;       // external SATA port (just forward value)
///    wire                          pcmd_cr;        // command list run - current - read only by software (set by HBA)
428 429
    wire                          pcmd_cr_set;    // command list run set
    wire                          pcmd_cr_reset;  // command list run reset
430
//    wire                          pcmd_fr;        // ahci_fis_receive:get_fis_busy - use frcv_busy
431 432 433

    wire                          pcmd_fre0;      // FIS enable copy to memory
    wire                          pcmd_fre = pcmd_fre0 || 1;     // FIS enable copy to memory
434 435 436
//    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
437
    wire                          pcmd_st;        // current value
438
    wire                          pfsm_started;   // H: FSM done, P: FSM started (enable sensing pcmd_st_cleared)
439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455
//clear_bsy_drq    
// Interrupt inputs
    wire                          sirq_TFE; // RWC: Task File Error Status
    wire                          sirq_IF;  // RWC: Interface Fatal Error Status (sect. 6.1.2)
    wire                          sirq_INF; // RWC: Interface Non-Fatal Error Status (sect. 6.1.2)
    wire                          sirq_OF;  // RWC: Overflow Status
    wire                          sirq_PRC; // RO:  PhyRdy changed Status
    wire                          sirq_PC;  // RO:  Port Connect Change Status
    wire                          sirq_DP;  // RWC: Descriptor Processed with "I" bit on
    wire                          sirq_UF;  // RO:  Unknown FIS
    wire                          sirq_SDB; // RWC: Set Device Bits Interrupt - Set Device bits FIS with 'I' bit set
    wire                          sirq_DS;  // RWC: DMA Setup FIS Interrupt - DMA Setup FIS received with 'I' bit set
    wire                          sirq_PS;  // RWC: PIO Setup FIS Interrupt - PIO Setup FIS received with 'I' bit set
    wire                          sirq_DHR; // RWC: D2H Register FIS Interrupt - D2H Register FIS received with 'I' bit set
// SCR1:SError (only inputs that are not available in sirq_* ones
                                  //sirq_PC;
                                  //sirq_UF
456
    wire                          serr_diag_X; // value of PxSERR.DIAG.X
457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475

     
    
// SCR0: SStatus
    wire                          ssts_ipm_dnp;      // device not present or communication not established
    wire                          ssts_ipm_active;   // device in active state
    wire                          ssts_ipm_part;     // device in partial state
    wire                          ssts_ipm_slumb;    // device in slumber state
    wire                          ssts_ipm_devsleep; // device in DevSleep state
    
    wire                          ssts_spd_dnp;      // device not present or communication not established
    wire                          ssts_spd_gen1;     // Gen 1 rate negotiated
    wire                          ssts_spd_gen2;     // Gen 2 rate negotiated
    wire                          ssts_spd_gen3;     // Gen 3 rate negotiated
    
    wire                          ssts_det_ndnp;     // no device detected, phy communication not established
    wire                          ssts_det_dnp;      // device detected, but phy communication not established
    wire                          ssts_det_dp;       // device detected, phy communication established
    wire                          ssts_det_offline;  // device detected, phy communication established
476 477
    wire                    [3:0] ssts_det;          // current value of PxSSTS.DET
    
478 479
 // SCR2:SControl (written by software only)
    wire                    [3:0] sctl_det;          // Device detection initialization requested
480 481
    wire                          sctl_det_changed;  // Software had written new value to sctl_det
    wire                          sctl_det_reset;    // clear sctl_det_changed
482 483 484
    
    wire                          pxci0_clear;       // PxCI clear
    wire                          pxci0;             // pxCI current value
485
    wire                          hba_rst_done;      // HBA reset done - clear GHC.HR (and some other regs)
486
    
487 488 489
    wire                          comreset_send0; // just disabling it
    
    
490
    wire                    [9:0] last_jump_addr;
491 492
    wire                   [31:0] debug_dma;
    wire                   [31:0] debug_dma1;
Andrey Filippov's avatar
Andrey Filippov committed
493
    wire                   [31:0] debug_dma_h2d;
494 495 496 497

    wire                          unsolicited_en;    // enable processing of cominit_got and PxERR.DIAG.W interrupts from
                                                     // this bit is reset at reset, set when PxSSTS.DET==3 or PxSCTL.DET==4

498 499 500
    
    assign comreset_send = comreset_send0 && 0;
    
501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518
    // Async FF
    always @ (posedge mrst or posedge mclk) begin
        if (mrst) en_port <= 0;
        else      en_port <= 1;
    end
    
/*
    reg                     [1:0] port_en;           //disable port signals until initialized from the hardware (currently - PLL)
    wire                          ports_rst = ~port_en[1];
    always @ (posedge mclk) begin
        if      (port_arst_any)       port_en[0] <= 0;
        else if (mrst)                port_en[0] <= 1;
        
        if      (port_arst_any)       port_en[1] <= 0;
        else if (!mrst && port_en[0]) port_en[1] <= 1;
        
    end
*/    
519 520


521 522 523 524 525 526 527 528 529
    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
530

531 532 533 534 535
        .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
536

537 538
        .phy_ready                (phy_ready),         // input
        .syncesc_send             (syncesc_send),      // output
539
        .comreset_send            (comreset_send0),     // output
540
        .syncesc_send_done        (syncesc_send_done), // input
541 542
        .cominit_got              (cominit_got),       // input
        .set_offline              (set_offline),       // output
543
//        .x_rdy_collision          (x_rdy_collision),   // input 
544 545 546
        
        .send_R_OK                (send_R_OK),         // output
        .send_R_ERR               (send_R_ERR),        // output
547
        
548
///        .update_pending           (update_regs_pending),// input
549 550
        .update_all               (update_all_regs),   // output
        .update_busy              (update_regs_busy),  // input
551 552 553 554 555 556 557 558 559 560 561 562
///        .update_gis               (update_GHC__IS),    // output
///        .update_pis               (update_HBA_PORT__PxIS),   // output
///        .update_ssts              (update_HBA_PORT__PxSSTS), // output
///        .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
563 564
        .pcmd_cr_set              (pcmd_cr_set),       // output
        .pcmd_cr_reset            (pcmd_cr_reset),     // output
565 566
//        .pcmd_fr                  (pcmd_fr),           // output
//        .pcmd_clear_bsy_drq       (pcmd_clear_bsy_drq),// output
567
        .pcmd_clo                 (pcmd_clo),          // input
568
//        .pcmd_clear_st            (pcmd_clear_st),     // output
569
        .pcmd_st                  (pcmd_st),           // input
570 571
        .pfsm_started             (pfsm_started),      // output
        .pcmd_st_cleared          (pcmd_st_cleared),   // input 
572 573 574 575 576 577 578 579 580 581 582 583
        .sirq_TFE                 (sirq_TFE),          // output
        .sirq_IF                  (sirq_IF),           // output
        .sirq_INF                 (sirq_INF),          // output
        .sirq_OF                  (sirq_OF),           // output
        .sirq_PRC                 (sirq_PRC),          // output
        .sirq_PC                  (sirq_PC),           // output
        .sirq_DP                  (sirq_DP),           // output
        .sirq_UF                  (sirq_UF),           // output
        .sirq_SDB                 (sirq_SDB),          // output
        .sirq_DS                  (sirq_DS),           // output
        .sirq_PS                  (sirq_PS),           // output
        .sirq_DHR                 (sirq_DHR),          // output
584
        .serr_diag_X              (serr_diag_X),       // input
585 586 587 588 589 590 591 592 593 594 595 596 597
        .ssts_ipm_dnp             (ssts_ipm_dnp),      // output
        .ssts_ipm_active          (ssts_ipm_active),   // output
        .ssts_ipm_part            (ssts_ipm_part),     // output
        .ssts_ipm_slumb           (ssts_ipm_slumb),    // output
        .ssts_ipm_devsleep        (ssts_ipm_devsleep), // output
        .ssts_spd_dnp             (ssts_spd_dnp),      // output
        .ssts_spd_gen1            (ssts_spd_gen1),     // output
        .ssts_spd_gen2            (ssts_spd_gen2),     // output
        .ssts_spd_gen3            (ssts_spd_gen3),     // output
        .ssts_det_ndnp            (ssts_det_ndnp),     // output
        .ssts_det_dnp             (ssts_det_dnp),      // output
        .ssts_det_dp              (ssts_det_dp),       // output
        .ssts_det_offline         (ssts_det_offline),  // output
598
        .ssts_det                 (ssts_det),          // input[3:0]
599 600
///        .sctl_ipm                 (sctl_ipm),          // input[3:0] 
///        .sctl_spd                 (sctl_spd),          // input[3:0] 
601
        .sctl_det                 (sctl_det),          // input[3:0] 
602 603
        .sctl_det_changed         (sctl_det_changed),  // input 
        .sctl_det_reset           (sctl_det_reset),    // output
604
        .hba_rst_done             (hba_rst_done),      // output
605 606
        .pxci0_clear              (pxci0_clear),       // output
        .pxci0                    (pxci0),             // input
607

608
///        .dma_prd_done             (dma_prd_done),       // input
609 610 611
        .dma_prd_irq_clear        (dma_prd_irq_clear),  // output
        .dma_prd_irq_pend         (dma_prd_irq_pend),   // input
        
612
        .dma_cmd_busy             (dma_cmd_busy),       // input
613
///        .dma_cmd_done             (dma_cmd_done),       // input
614
        .dma_cmd_abort            (dma_cmd_abort_fsm),  // output
615 616 617
        .dma_abort_done           (dma_abort_done),     // input
        .fis_first_invalid        (frcv_first_invalid),// input
        .fis_first_flush          (frcv_first_flush),  // output
618
        
619 620 621
        .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'
        .bist_bits                (d2h_data[23:16]),    // bits that define built-in self test
622

623 624 625 626 627 628 629 630 631 632 633 634 635
        .get_dsfis                (frcv_get_dsfis),     // output
        .get_psfis                (frcv_get_psfis),     // output
        .get_rfis                 (frcv_get_rfis),      // output
        .get_sdbfis               (frcv_get_sdbfis),    // output
        .get_ufis                 (frcv_get_ufis),      // output
        .get_data_fis             (frcv_get_data_fis),  // output
        .get_ignore               (frcv_get_ignore),    // output
///     .get_fis_busy             (frcv_busy),          // input
        .get_fis_done             (frcv_done),          // input
        .fis_ok                   (frcv_ok),            // input
        .fis_err                  (frcv_err),           // input
        .fis_ferr                 (frcv_ferr),          // input
        .fis_extra                (frcv_extra || dma_extra_din), // input // more data got from FIS than DMA can accept. Does not deny fis_ok. May have latency
636
        
637 638 639 640
        .set_update_sig           (frcv_set_update_sig),// output
///        .pUpdateSig            (frcv_pUpdateSig),    // input
///        .sig_available         (frcv_sig_available), // input
        .update_sig               (frcv_update_sig),    // output
641
        
642 643 644 645 646 647 648 649 650 651 652
        .update_err_sts           (frcv_update_err_sts),// output
        .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
        .clear_xfer_cntr          (frcv_clear_xfer_cntr), //output Clear pXferCntr
        .decr_dwcr                (frcv_decr_dwcr),     // output increment pXferCntr after transmit by data transmitted)
        .decr_dwcw                (frcv_decr_dwcw),     // output increment pXferCntr after transmit by data transmitted)
653
//      .decr_DXC_dw     (data_out_dwords),    // output[11:2] **** Probably not needed
654
        .pxcmd_fre                ( pcmd_fre), // input
655 656 657 658
        .pPioXfer                 (pPioXfer),           // input      
        .tfd_sts                  (tfd_sts),            // input[7:0] 
///        .tfd_err            (tfd_err),            // input[7:0] 
        .fis_i                    (fis_i),              // input
659
///        .sdb_n           (sdb_n),              // input
660
        .dma_a                    (dma_a),              // input
661
///        .dma_d           (dma_d),              // input
662 663
        .pio_i                    (pio_i),              // input
        .pio_d                    (pio_d),              // input
664 665 666
///        .sactive0        (sactive0),            // input
///        .pio_es          (pio_es),             // input[7:0] 
///        .xfer_cntr       (xfer_cntr[31:2]),    // input[31:2] 
667
        .xfer_cntr_zero           (xfer_cntr_zero),     // input
668
        
669 670 671 672 673
        .fetch_cmd                (fsnd_fetch_cmd),     // output
        .cfis_xmit                (fsnd_cfis_xmit),     // output
        .dx_xmit                  (fsnd_dx_xmit),       // output
        .atapi_xmit               (fsnd_atapi_xmit),    // output
        .xmit_done                (fsnd_done),          // input
674
///        .xmit_busy       (fsnd_busy),          // input
675 676
        .clearCmdToIssue          (fsnd_clearCmdToIssue),// output // From CFIS:SUCCESS 
        .pCmdToIssue              (fsnd_pCmdToIssue),   // input
677
        .dx_err                   (fsnd_dx_err),        // input[2:0] 
678
///        .ch_prdtl        (prdtl),              // input[15:0] 
679 680 681 682 683 684
        .ch_c                     (fsnd_ch_c),          // input
        .ch_b                     (fsnd_ch_b),          // input
        .ch_r                     (fsnd_ch_r),          // input
        .ch_p                     (fsnd_ch_p),          // input
        .ch_w                     (fsnd_ch_w),          // input
        .ch_a                     (fsnd_ch_a),          // input
685 686
///        .ch_cfl          (fsnd_ch_cfl),        // input[4:0] 
///        .dwords_sent     (data_out_dwords)     // input[11:0] ????
687
        .unsolicited_en           (unsolicited_en),     // input
688
        .last_jump_addr           (last_jump_addr)
689
    );
690

691 692 693
wire debug_data_in_ready;       // output
wire debug_fis_end_w;           // output
wire[1:0] debug_fis_end_r;      // output[1:0] 
694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711
wire[1:0] debug_get_fis_busy_r; // output[1:0]
 

localparam DATA_TYPE_DMA =      0;
localparam DATA_TYPE_FIS_HEAD = 1;
localparam DATA_TYPE_OK =       2;
localparam DATA_TYPE_ERR =      3;

reg [12:0] debug_d2h_length;
reg [12:0] debug_d2h_length_prev;
reg        was_good_bad;
reg        was_good_bad_prev;

always @(posedge mclk) if (d2h_ready && d2h_valid) begin
    if      (d2h_type == DATA_TYPE_FIS_HEAD) debug_d2h_length_prev <= debug_d2h_length;

    if      (d2h_type == DATA_TYPE_FIS_HEAD) debug_d2h_length <= 0;
    else if (d2h_type == DATA_TYPE_DMA)      debug_d2h_length <= debug_d2h_length  + 1;
712

713 714 715 716 717
    if      (d2h_type == DATA_TYPE_FIS_HEAD) was_good_bad_prev <= was_good_bad;

    if      ((d2h_type == DATA_TYPE_OK) || (d2h_type == DATA_TYPE_ERR)) was_good_bad <= (d2h_type == DATA_TYPE_OK);
    
end
718

719
    axi_ahci_regs #(
Andrey Filippov's avatar
Andrey Filippov committed
720 721 722
        .ADDRESS_BITS          (ADDRESS_BITS),
        .HBA_RESET_BITS        (HBA_RESET_BITS),
        .RESET_TO_FIRST_ACCESS (RESET_TO_FIRST_ACCESS)
723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758
    ) axi_ahci_regs_i (
        .aclk             (aclk),            // input
        .arst             (arst),            // input
        .awaddr           (awaddr),          // input[31:0] 
        .awvalid          (awvalid),         // input
        .awready          (awready),         // output
        .awid             (awid),            // input[11:0] 
        .awlen            (awlen),           // input[3:0] 
        .awsize           (awsize),          // input[1:0] 
        .awburst          (awburst),         // input[1:0] 
        .wdata            (wdata),           // input[31:0] 
        .wvalid           (wvalid),          // input
        .wready           (wready),          // output
        .wid              (wid),             // input[11:0] 
        .wlast            (wlast),           // input
        .wstb             (wstb),            // input[3:0] 
        .bvalid           (bvalid),          // output
        .bready           (bready),          // input
        .bid              (bid),             // output[11:0] 
        .bresp            (bresp),           // output[1:0] 
        .araddr           (araddr),          // input[31:0] 
        .arvalid          (arvalid),         // input
        .arready          (arready),         // output
        .arid             (arid),            // input[11:0] 
        .arlen            (arlen),           // input[3:0] 
        .arsize           (arsize),          // input[1:0] 
        .arburst          (arburst),         // input[1:0] 
        .rdata            (rdata),           // output[31:0] 
        .rvalid           (rvalid),          // output
        .rready           (rready),          // input
        .rid              (rid),             // output[11:0] 
        .rlast            (rlast),           // output
        .rresp            (rresp),           // output[1:0] 
        .soft_write_addr  (soft_write_addr), // output[9:0] 
        .soft_write_data  (soft_write_data), // output[31:0] 
        .soft_write_en    (soft_write_en),   // output
759
        .hba_arst         (hba_arst),        // output // does not include arst
Andrey Filippov's avatar
Andrey Filippov committed
760
        .port_arst_any    (port_arst_any),   // async set by arst
761
        .port_arst        (port_arst),       // output // does not include arst
762
        .hba_clk          (mclk),            // input
763
        .hba_rst          (mrst),            // input   // deasserted when mclk is stable
764 765 766 767
        .hba_addr         (regs_addr),       // input[9:0] 
        .hba_we           (regs_we),         // input
        .hba_re           (regs_re),         // input[1:0] 
        .hba_din          (regs_din),        // input[31:0] 
768 769 770 771
        .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 
772 773
        .afi_wcache       (axi_wr_cache_mode),// output[3:0] reg 
        .afi_rcache       (axi_rd_cache_mode),// output[3:0] reg 
774 775
        .afi_cache_set    (set_axi_cache_mode), // output
        .was_hba_rst      (was_hba_rst),     // output 
776
        .was_port_rst     (was_port_rst),    // output 
777 778 779 780 781 782 783 784
        .debug_in0        ({ 2'b0,
                             was_good_bad_prev,
                             debug_d2h_length_prev[12:0],
                             2'b0,
                             was_good_bad,
                             debug_d2h_length[12:0]
                             }),
                             
785 786
//        .debug_in1        ({xclk_period[7:0], // lower 8 bits of 12-bit value. Same frequency would be 0x800 (msb opposite to 3 next bits)
//                            debug_dma1[23:0]}),      // debug_in_link),   // input[31:0]
787
        .debug_in1        ({debug_in_link[15:8],
788
                            debug_dma1[23:0]}),      // debug_in_link),   // input[31:0]
Andrey Filippov's avatar
Andrey Filippov committed
789
        .debug_in2        (debug_in_phy),    // input[31:0]     // debug from phy/link
790
//        .debug_in3        ({22'b0, last_jump_addr[9:0]}) // input[31:0]// Last jump address in the AHDCI sequencer
791
        .debug_in3        ({debug_in_link[7:0],
792
                            frcv_busy,frcv_ok, // 2'b0,
793
`ifdef USE_DATASCOPE
794
                             datascope_waddr[9:0],
795 796 797
`else
                             10'b0,
`endif                             
798 799
                            frcv_err,frcv_ferr, // 2'b0,
                             last_jump_addr[9:0]}) // input[31:0]// Last jump address in the AHDCI sequencer
Andrey Filippov's avatar
Andrey Filippov committed
800 801 802 803 804 805 806 807 808 809
`ifdef USE_DRP
       ,.drp_en           (drp_en),          // output reg 
        .drp_we           (drp_we),          // output reg 
        .drp_addr         (drp_addr),        // output[14:0] reg 
        .drp_di           (drp_di),          // output[15:0] reg 
        .drp_rdy          (drp_rdy),         // input
        .drp_do           (drp_do)           // input[15:0] 
`endif    
        
        
810 811 812 813
`ifdef USE_DATASCOPE
        ,.datascope_clk   (datascope_clk),   // input
        .datascope_waddr  (datascope_waddr), // input[9:0] 
        .datascope_we     (datascope_we),    // input
814 815 816 817 818 819
        .datascope_di     (datascope_di),    // input[31:0] 
        
        .datascope1_clk   (datascope1_clk),  // input
        .datascope1_waddr (datascope1_waddr),// input[9:0] 
        .datascope1_we    (datascope1_we),   // input
        .datascope1_di    (datascope1_di)    // input[31:0] 
820
`endif        
821
///        .debug_in         (debug_in[31:0])
822
    );
823 824 825
    ahci_ctrl_stat #(
        .ADDRESS_BITS            (ADDRESS_BITS)
    ) ahci_ctrl_stat_i (
826 827 828 829 830 831 832 833 834 835
        .mrst                    (mrst),                    // input
        .mclk                    (mclk),                    // input
        .was_hba_rst             (was_hba_rst),             // input
        .was_port_rst            (was_port_rst),            // input
        .soft_write_addr         (soft_write_addr),         // input[9:0] 
        .soft_write_data         (soft_write_data),         // input[31:0] 
        .soft_write_en           (soft_write_en),           // input
        .regs_addr               (regs_saddr),              // output[9:0] reg 
        .regs_we                 (regs_we_acs),             // output reg 
        .regs_din                (regs_din_from_acs),       // output[31:0] reg 
836
        .update_pending          (), /// update_regs_pending),     // output
837 838
        .update_all              (update_all_regs),         // input
        .update_busy             (update_regs_busy),        // output
839 840 841 842 843 844 845 846 847 848
///        .st01_pending            (st01_pending),            // output reg 
///        .st10_pending            (st10_pending),            // output reg 
///        .st_pending_reset        (st_pending_reset),        // input
        
        .update_gis              (1'b0), // update_GHC__IS),          // input
        .update_pis              (1'b0), // update_HBA_PORT__PxIS),   // input
        .update_ssts             (1'b0), // update_HBA_PORT__PxSSTS), // input
        .update_serr             (1'b0), // update_HBA_PORT__PxSERR), // input
        .update_pcmd             (1'b0), // update_HBA_PORT__PxCMD),  // input
        .update_pci              (1'b0), // update_HBA_PORT__PxCI),   // input
849
        .update_ghc              (1'b0), // update _GHC_GHC,          // input
850
        
Andrey Filippov's avatar
Andrey Filippov committed
851
//        .pcmd_clear_icc          (1'b0), // pcmd_clear_icc),          // input
852
        .pcmd_esp                (pcmd_esp),                // input
853
        .pcmd_cr                 (), //pcmd_cr),                 // output
854 855
        .pcmd_cr_set             (pcmd_cr_set),             // input
        .pcmd_cr_reset           (pcmd_cr_reset),           // input
856
        .pcmd_fr                 (frcv_busy),               // input
857
        .pcmd_fre                (pcmd_fre0),               // output
858
        .pcmd_clear_bsy_drq      (frcv_clear_bsy_drq),      // input
859
        .pcmd_clo                (pcmd_clo),                // output
860
        .pcmd_clear_st           (1'b0), // pcmd_clear_st),           // input
861
        .pcmd_st                 (pcmd_st),                 // output
862 863
        .pfsm_started            (pfsm_started),            // input
        .pcmd_st_cleared         (pcmd_st_cleared),         // output reg 
864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882
        .sirq_TFE                (sirq_TFE),                // input
        .sirq_IF                 (sirq_IF),                 // input
        .sirq_INF                (sirq_INF),                // input
        .sirq_OF                 (sirq_OF),                 // input
        .sirq_PRC                (sirq_PRC),                // input
        .sirq_PC                 (sirq_PC),                 // input
        .sirq_DP                 (sirq_DP),                 // input
        .sirq_UF                 (sirq_UF),                 // input
        .sirq_SDB                (sirq_SDB),                // input
        .sirq_DS                 (sirq_DS),                 // input
        .sirq_PS                 (sirq_PS),                 // input
        .sirq_DHR                (sirq_DHR),                // input
        .serr_DT                 (serr_DT),                 // input
        .serr_DS                 (serr_DS),                 // input
        .serr_DH                 (serr_DH),                 // input
        .serr_DC                 (serr_DC),                 // input
        .serr_DB                 (serr_DB),                 // input
        .serr_DW                 (serr_DW),                 // input
        .serr_DI                 (serr_DI),                 // input
883
        .serr_EE                 (serr_EE),                 // input
884 885 886 887 888
        .serr_EP                 (serr_EP),                 // input
        .serr_EC                 (serr_EC),                 // input
        .serr_ET                 (serr_ET),                 // input
        .serr_EM                 (serr_EM),                 // input
        .serr_EI                 (serr_EI),                 // input
889
        .serr_diag_X             (serr_diag_X),             // output
890 891 892 893 894 895 896 897 898 899 900 901 902
        .ssts_ipm_dnp            (ssts_ipm_dnp),            // input
        .ssts_ipm_active         (ssts_ipm_active),         // input
        .ssts_ipm_part           (ssts_ipm_part),           // input
        .ssts_ipm_slumb          (ssts_ipm_slumb),          // input
        .ssts_ipm_devsleep       (ssts_ipm_devsleep),       // input
        .ssts_spd_dnp            (ssts_spd_dnp),            // input
        .ssts_spd_gen1           (ssts_spd_gen1),           // input
        .ssts_spd_gen2           (ssts_spd_gen2),           // input
        .ssts_spd_gen3           (ssts_spd_gen3),           // input
        .ssts_det_ndnp           (ssts_det_ndnp),           // input
        .ssts_det_dnp            (ssts_det_dnp),            // input
        .ssts_det_dp             (ssts_det_dp),             // input
        .ssts_det_offline        (ssts_det_offline),        // input
903
        .ssts_det                (ssts_det),                // output[3:0]
904 905
        .sctl_ipm                (sctl_ipm),                // output[3:0] reg 
        .sctl_spd                (sctl_spd),                // output[3:0] reg 
906 907 908
        .sctl_det                (sctl_det),                // output[3:0] reg
        .sctl_det_changed        (sctl_det_changed),        // output reg 
        .sctl_det_reset          (sctl_det_reset),          // input
909 910
        .pxci0_clear             (pxci0_clear),             // input
        .pxci0                   (pxci0),                   // output
911
        .hba_reset_done          (hba_rst_done),            // input
912
        .unsolicited_en          (unsolicited_en),          // output
913
        .irq                     (irq)                      // output reg 
914
    );
915 916

    ahci_dma ahci_dma_i (
917 918 919 920
        .mrst                  (mrst),          // input
        .hrst                  (hrst),          // input
        .mclk                  (mclk),          // input
        .hclk                  (hclk),          // input
921 922
//        .ctba                  (regs_dout[31:7]),// input[31:7] 
        .ctba                  (regs_dout[31:4]),// input[31:4] 
923 924 925
        .ctba_ld               (ctba_ld),       // input
        .prdtl                 (prdtl),         // input[15:0] 
        .dev_wr                (dev_wr),        // input
926 927
        .cmd_start             (dma_cmd_start), // input
        .prd_start             (dma_prd_start), // input
928
        .cmd_abort             (dma_cmd_abort_xmit || dma_cmd_abort_fsm), // input
929 930
        .axi_wr_cache_mode     (axi_wr_cache_mode), // input[3:0] 
        .axi_rd_cache_mode     (axi_rd_cache_mode), // input[3:0] 
931 932
        .set_axi_wr_cache_mode (set_axi_cache_mode), // input
        .set_axi_rd_cache_mode (set_axi_cache_mode), // input
933 934
        .ct_busy               (dma_ct_busy),   // output reg 
        .ct_addr               (dma_ct_addr),   // input[4:0] 
935
        .ct_re                 (dma_ct_re),     // input[1:0]
936
        .ct_data               (dma_ct_data),   // output[31:0] reg 
937
        .prd_done              (), /// dma_prd_done),  // output
938 939 940 941
        
        .prd_irq_clear         (dma_prd_irq_clear),// input
        .prd_irq_pend          (dma_prd_irq_pend), // output reg
        
942
        .cmd_busy              (dma_cmd_busy), // dma_cmd_busy),  // output reg Some data to transmit!
943
        .cmd_done              (dma_cmd_done),  // output
944 945 946
        .abort_busy            (dma_abort_busy),
        .abort_done            (dma_abort_done),
        .axi_mismatch          (axi_mismatch),  // handled, but may report as an error - axi counters are 0, but calculated ones are not
947 948 949
        .sys_out               (dma_dout),      // output[31:0] 
        .sys_dav               (dma_dav),       // output
        .sys_re                (dma_re),        // input
950
        .last_h2d_data         (last_h2d_data), // output
951 952 953
        .sys_in                (d2h_data),      // input[31:0] 
        .sys_nfull             (dma_in_ready),  // output
        .sys_we                (dma_we),        // input
954
        .extra_din             (dma_extra_din), // output reg
955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997
        .afi_awaddr        (afi_awaddr),        // output[31:0] 
        .afi_awvalid       (afi_awvalid),       // output
        .afi_awready       (afi_awready),       // input
        .afi_awid          (afi_awid),          // output[5:0] 
        .afi_awlock        (afi_awlock),        // output[1:0] 
        .afi_awcache       (afi_awcache),       // output[3:0] reg 
        .afi_awprot        (afi_awprot),        // output[2:0] 
        .afi_awlen         (afi_awlen),         // output[3:0] 
        .afi_awsize        (afi_awsize),        // output[1:0] 
        .afi_awburst       (afi_awburst),       // output[1:0] 
        .afi_awqos         (afi_awqos),         // output[3:0] 
        .afi_wdata         (afi_wdata),         // output[63:0] 
        .afi_wvalid        (afi_wvalid),        // output
        .afi_wready        (afi_wready),        // input
        .afi_wid           (afi_wid),           // output[5:0] 
        .afi_wlast         (afi_wlast),         // output
        .afi_wstrb         (afi_wstrb),         // output[7:0] 
        .afi_bvalid        (afi_bvalid),        // input
        .afi_bready        (afi_bready),        // output
        .afi_bid           (afi_bid),           // input[5:0] 
        .afi_bresp         (afi_bresp),         // input[1:0] 
        .afi_wcount        (afi_wcount),        // input[7:0] 
        .afi_wacount       (afi_wacount),       // input[5:0] 
        .afi_wrissuecap1en (afi_wrissuecap1en), // output
        .afi_araddr        (afi_araddr),        // output[31:0] 
        .afi_arvalid       (afi_arvalid),       // output
        .afi_arready       (afi_arready),       // input
        .afi_arid          (afi_arid),          // output[5:0] 
        .afi_arlock        (afi_arlock),        // output[1:0] 
        .afi_arcache       (afi_arcache),       // output[3:0] reg 
        .afi_arprot        (afi_arprot),        // output[2:0] 
        .afi_arlen         (afi_arlen),         // output[3:0] 
        .afi_arsize        (afi_arsize),        // output[1:0] 
        .afi_arburst       (afi_arburst),       // output[1:0] 
        .afi_arqos         (afi_arqos),         // output[3:0] 
        .afi_rdata         (afi_rdata),         // input[63:0] 
        .afi_rvalid        (afi_rvalid),        // input
        .afi_rready        (afi_rready),        // output
        .afi_rid           (afi_rid),           // input[5:0] 
        .afi_rlast         (afi_rlast),         // input
        .afi_rresp         (afi_rresp),         // input[1:0] 
        .afi_rcount        (afi_rcount),        // input[7:0] 
        .afi_racount       (afi_racount),       // input[2:0] 
998 999 1000
        .afi_rdissuecap1en (afi_rdissuecap1en), // output
        .debug_out         (debug_dma),          // output[31:0]
        .debug_out1        (debug_dma1)          // output[31:0]
Andrey Filippov's avatar
Andrey Filippov committed
1001
        ,.debug_dma_h2d    (debug_dma_h2d)
1002 1003 1004
    );

    ahci_fis_receive #(
1005
        .ADDRESS_BITS      (ADDRESS_BITS)
1006
    ) ahci_fis_receive_i (
1007 1008
        .hba_rst           (mrst),                   // input
        .mclk              (mclk),                   // input
1009
        .pcmd_st_cleared   (pcmd_st_cleared),        // input
1010
        .fis_first_vld     (frcv_first_vld),         // output reg 
1011 1012
        .fis_first_invalid (frcv_first_invalid),     // output
        .fis_first_flush   (frcv_first_flush),       // input
1013

1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026
        .get_dsfis         (frcv_get_dsfis),         // input
        .get_psfis         (frcv_get_psfis),         // input
        .get_rfis          (frcv_get_rfis),          // input
        .get_sdbfis        (frcv_get_sdbfis),        // input
        .get_ufis          (frcv_get_ufis),          // input
        .get_data_fis      (frcv_get_data_fis),      // input
        .get_ignore        (frcv_get_ignore),        // input
        
        .get_fis_busy      (frcv_busy),              // output reg 
        .get_fis_done      (frcv_done),              // output reg 
        .fis_ok            (frcv_ok),                // output reg 
        .fis_err           (frcv_err),               // output reg 
        .fis_ferr          (frcv_ferr),              // output
1027

1028 1029 1030
        .dma_prds_done     (dma_cmd_done),           // input
        .fis_extra         (frcv_extra),             // output

1031
        .set_update_sig    (frcv_set_update_sig),    // input
1032 1033
        .pUpdateSig        (), /// frcv_pUpdateSig),        // output
        .sig_available     (), ///frcv_sig_available),     // output reg 
1034
        .update_sig        (frcv_update_sig),        // input
1035 1036
        
        .update_err_sts    (frcv_update_err_sts),    // input
1037 1038
        .update_pio        (frcv_update_pio),        // input  update PxTFD.STS and PxTFD.ERR from pio_* (entry PIO:Update)
        
1039
        .update_prdbc      (frcv_update_prdbc),      // input
1040 1041
        .clear_prdbc       (fsnd_fetch_cmd),         // input save resources - clear prdbc for every commnad
        
1042
        .clear_bsy_drq     (frcv_clear_bsy_drq),     // input
1043 1044
        .clear_bsy_set_drq (frcv_clear_bsy_set_drq), // input
        
1045 1046 1047
        .set_bsy           (frcv_set_bsy),           // input
        .set_sts_7f        (frcv_set_sts_7f),        // input
        .set_sts_80        (frcv_set_sts_80),        // input
1048
        .clear_xfer_cntr (frcv_clear_xfer_cntr),     // input Clear pXferCntr
1049 1050
        .decr_dwcr         (frcv_decr_dwcr),         // input
        .decr_dwcw         (frcv_decr_dwcw),         // input
1051 1052 1053
        .decr_DXC_dw       (data_out_dwords),        // input[11:2]
        .pcmd_fre          (pcmd_fre),               // input
         
1054
        .pPioXfer          (pPioXfer),               // output reg 
1055
        
1056
        .tfd_sts           (tfd_sts),                // output[7:0] 
1057
        .tfd_err           (), /// tfd_err),                // output[7:0] 
1058
        .fis_i             (fis_i),                  // output reg 
1059
        .sdb_n             (), /// sdb_n),                  // output reg 
1060
        .dma_a             (dma_a),                  // output reg 
1061
        .dma_d             (), /// dma_d),                  // output reg 
1062 1063
        .pio_i             (pio_i),                  // output reg 
        .pio_d             (pio_d),                  // output reg 
1064 1065
        .pio_es            (), /// pio_es),                 // output[7:0] reg 
        .sactive0          (), /// sactive0),               // output reg 
1066 1067
        .xfer_cntr         (xfer_cntr[31:2]),        // output[31:2] 
        .xfer_cntr_zero    (xfer_cntr_zero),         // output reg
1068
        .data_in_dwords    (), /// data_in_dwords),         // output[11:0] 
1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079
         
        .reg_addr          (regs_waddr),             // output[9:0] reg 
        .reg_we            (regs_we_freceive),       // output reg 
        .reg_data          (regs_din_from_freceive), // output[31:0] reg 
        .hba_data_in       (d2h_data),               // input[31:0] 
        .hba_data_in_type  (d2h_type),               // input[1:0] 
        .hba_data_in_valid (d2h_valid),              // input
        .hba_data_in_many  (d2h_many),               // input
        .hba_data_in_ready (d2h_ready),              // output
        .dma_in_ready      (dma_in_ready),           // input
        .dma_in_valid      (dma_we)                  // output
1080 1081 1082 1083 1084
        
        ,.debug_data_in_ready (debug_data_in_ready), // output
        .debug_fis_end_w      (debug_fis_end_w),     // output
        .debug_fis_end_r      (debug_fis_end_r),     // output[1:0] 
        .debug_get_fis_busy_r (debug_get_fis_busy_r) // output[1:0] 
1085
    );
1086 1087
wire ahci_fis_transmit_busy;
wire [9:0] xmit_dbg_01;
1088
    ahci_fis_transmit #(
1089 1090 1091 1092
        .PREFETCH_ALWAYS  (PREFETCH_ALWAYS),
        .READ_REG_LATENCY (READ_REG_LATENCY),
        .READ_CT_LATENCY  (READ_CT_LATENCY),
        .ADDRESS_BITS     (ADDRESS_BITS)
1093
    ) ahci_fis_transmit_i (
1094 1095
//        .hba_rst           (mrst),                 // input TODO: Reset when !PxCMD.ST? pcmd_st
        .hba_rst           (mrst || !pcmd_st),     // input TODO: Reset when !PxCMD.ST? pcmd_st
1096
        .mclk              (mclk),                 // input
Andrey Filippov's avatar
Andrey Filippov committed
1097
        .pcmd_st_cleared   (pcmd_st_cleared),      // input
1098 1099
        .fetch_cmd         (fsnd_fetch_cmd),       // input
        .cfis_xmit         (fsnd_cfis_xmit),       // input
1100
        .dx_xmit           (fsnd_dx_xmit),         // input
1101
        .atapi_xmit        (fsnd_atapi_xmit),      // input
1102
        
1103
        .done              (fsnd_done),            // output reg 
1104
        .busy              (ahci_fis_transmit_busy), /// fsnd_busy),            // output reg 
1105 1106
        .clearCmdToIssue   (fsnd_clearCmdToIssue), // input
        .pCmdToIssue       (fsnd_pCmdToIssue),     // output
1107
        .xmit_ok           (xmit_ok),              // input
1108
        .xmit_err          (xmit_err),             // input
1109 1110
        .syncesc_recv      (syncesc_recv),         // input
        .xrdy_collision    (x_rdy_collision),      // input
1111 1112 1113 1114 1115 1116 1117 1118
        .dx_err            (fsnd_dx_err),          // output[1:0] 
        .ch_prdtl          (prdtl),                // output[15:0]
        .ch_c              (fsnd_ch_c),            // output
        .ch_b              (fsnd_ch_b),            // output
        .ch_r              (fsnd_ch_r),            // output
        .ch_p              (fsnd_ch_p),            // output
        .ch_w              (fsnd_ch_w),            // output
        .ch_a              (fsnd_ch_a),            // output
1119
        .ch_cfl            (), /// fsnd_ch_cfl),          // output[4:0] 
1120 1121 1122 1123 1124 1125

        .dwords_sent       (data_out_dwords),      // output[11:0] reg
        .reg_addr          (regs_raddr),           // output[9:0] reg 
        .reg_re            (regs_re_ftransmit),    // output[1:0]
        .reg_rdata         (regs_dout),            // input[31:0] 
        .xfer_cntr         (xfer_cntr[31:2]),      // input[31:2] 
1126
        .xfer_cntr_zero    (xfer_cntr_zero),       // input 
1127 1128 1129 1130 1131
        .dma_ctba_ld       (ctba_ld),              // output
        .dma_start         (dma_cmd_start),        // output
        .dma_dev_wr        (dev_wr),               // output
        .dma_ct_busy       (dma_ct_busy),          // input
        .dma_prd_start     (dma_prd_start),        // output reg 
1132
        .dma_cmd_abort     (dma_cmd_abort_xmit),   // output reg
1133 1134 1135 1136 1137 1138
        .ct_addr           (dma_ct_addr),          // output[4:0] reg 
        .ct_re             (dma_ct_re),            // output[1:0]
        .ct_data           (dma_ct_data),          // input[31:0] 
        .dma_out           (dma_dout),             // input[31:0] 
        .dma_dav           (dma_dav),              // input
        .dma_re            (dma_re),               // output
1139
        .last_h2d_data     (last_h2d_data),        // input
1140 1141 1142 1143
        .todev_data        (h2d_data),             // output[31:0] reg 
        .todev_type        (h2d_type),             // output[1:0] reg 
        .todev_valid       (h2d_valid),            // output
        .todev_ready       (h2d_ready)             // input
1144
       ,.debug_01(xmit_dbg_01)
1145 1146
    );

1147
// Datascope code
1148
//`define DATASCOPE_V2
1149
// Datascope interface (write to memory that can be software-read)
1150 1151
`define DATASCOPE_FIS_DATA 1

Andrey Filippov's avatar
Andrey Filippov committed
1152 1153
`ifdef USE_DATASCOPE

1154 1155 1156 1157
    `ifdef DATASCOPE_V2
        reg    [ADDRESS_BITS-1:0] datascope_waddr_r;
        reg                 [1:0] datascope_run;
    //    reg                 [1:0] datascope_run;
Andrey Filippov's avatar
Andrey Filippov committed
1158
        
1159 1160 1161
        assign datascope_we = datascope_run[1];
        assign datascope_clk = mclk;
        assign datascope_waddr = datascope_waddr_r;
Andrey Filippov's avatar
Andrey Filippov committed
1162
        
1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173
         assign datascope_di = {
                                 debug_dma_h2d[3], // done_flush_mclk,
                                 debug_dma_h2d[2], // dout_vld,
                                 debug_dma_h2d[1], // dout_re,
                                 debug_dma_h2d[0], // last_DW,
                                 
                                 dma_dout[27:16],
                                 debug_dma_h2d[19:18], // 2'b0
                                 debug_dma_h2d[17],    // fifo_rd
                                 debug_dma_h2d[16:12], // raddr[4:0]
                                 debug_dma_h2d[11:8],  //fifo_do_vld[3:0]
Andrey Filippov's avatar
Andrey Filippov committed
1174
    
1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189
                                 debug_dma_h2d[7],    // fifo_dav
                                 debug_dma_h2d[6],    // fifo_dav2_w
                                 debug_dma_h2d[5],    // fifo_dav2
                                 debug_dma_h2d[4]     // flushing_mclk
         };
         
     //    dma_dout[
        
        always @ (posedge mclk) begin
            if      (mrst)                  datascope_run[0] <= 0;
            else if (dma_cmd_start)         datascope_run[0] <= 1;
            else if (dma_cmd_done)          datascope_run[0] <= 0;
            
            if (mrst || !datascope_run[0])  datascope_run[1] <= 0;
            else if (dma_dav)               datascope_run[1] <= 1;
1190
    
1191 1192
            if    (fsnd_cfis_xmit)          datascope_waddr_r <= 0;
            else if (datascope_we)          datascope_waddr_r <= datascope_waddr_r + 1;
1193
    
1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208
            
        end
    //`endif // DATASCOPE_V2
    `else
    //`ifdef DATASCOPE_V1
        `ifdef DATASCOPE_FIS_DATA
            datascope_timing #(
                .ADDRESS_BITS(10),
                .FIS_LEN(5)
            ) datascope_timing_i (
                .clk             (mclk), // input
                .rst             (mrst), // input
                .soft_write_addr (soft_write_addr), // input[9:0] 
                .soft_write_data (soft_write_data), // input[31:0] 
                .soft_write_en   (soft_write_en), // input
1209
                .cfis            (fsnd_cfis_xmit), // input command FIS - to reset dword counter
1210 1211 1212 1213 1214 1215 1216 1217
                .h2d_data        (h2d_data), // input[31:0] 
                .h2d_type        (h2d_type), // input[1:0] 
                .h2d_valid       (h2d_valid), // input
                .h2d_ready       (h2d_ready), // input
                .d2h_data        (d2h_data), // input[31:0] 
                .d2h_type        (d2h_type), // input[1:0] 
                .d2h_valid       (d2h_valid), // input
                .d2h_ready       (d2h_ready), // input
1218 1219
                .debug_link_send_data(debug_link_send_data), // input
                .debug_link_dmatp  (debug_link_dmatp),        // link received DMATp from device
1220
                .irq             (irq),           // system IRQ
1221 1222 1223 1224 1225
                .datascope_clk   (datascope_clk), // output
                .datascope_waddr (datascope_waddr), // output[9:0] reg 
                .datascope_we    (datascope_we), // output
                .datascope_di    (datascope_di) // output[31:0] reg 
            );
1226
        
1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273
        `else  // DATASCOPE_FIS_DATA  
            localparam DATASCOPE_CFIS_START=0;
            localparam DATASCOPE_INCOMING_POST=32;
            
            reg    [ADDRESS_BITS-1:0] datascope_waddr_r=0;
            reg                 [1:0] datascope_run;
            
            reg                       datascope_link_run;
            wire                      datascope_is_state_send_ready = (debug_in_link[4:0] == 16);
            wire                      datascope_is_state_idle =       (debug_in_link[4:0] == 22);
            reg                       datascope_was_state_send_ready;
            reg                 [3:0] datascope_id;
            
            wire                      datascope_incoming_start = debug_in_link[22];  // set_rcvr_wait; // start logging
            wire                      datascope_incoming_started = debug_in_phy[21:20] == 1;  // 
            wire                      datascope_incomining_preend = debug_in_phy[21]; // d2h_type_in[1
            reg                 [2:0] datascope_incoming_run;
            reg                 [7:0] datascope_incoming_cntr;
            reg                       datascope_receive_fis;
            reg                 [9:0] datascope_last_jump_addr=0;
            reg                 [1:0] datascope_new_jump = 0;
            reg                [15:0] datascope_jump_cntr = 0;
             
        //last_jump_addr[9:0]    
            always @(posedge mclk) begin
                if (mrst)  datascope_new_jump[0] <=  0;
                else       datascope_new_jump[0] <=   datascope_last_jump_addr != last_jump_addr;
                
                if (mrst)  datascope_new_jump[1] <=  0;
                else       datascope_new_jump[1] <=  datascope_new_jump[0];
                
                if (mrst)               datascope_last_jump_addr <=  0;
                if (datascope_new_jump) datascope_last_jump_addr <= last_jump_addr;
                
                if (datascope_we) datascope_jump_cntr <= datascope_jump_cntr+1;
                
                
            
                if      (mrst)                                                           datascope_receive_fis <= 0;
                else if (datascope_incoming_start)                                       datascope_receive_fis <= 1;
                else if (frcv_get_dsfis ||
                         frcv_get_psfis ||
                         frcv_get_rfis || 
                         frcv_get_sdbfis ||
                         frcv_get_ufis ||
                         frcv_get_data_fis ||
                         frcv_get_ignore)                                                datascope_receive_fis <= 0;
1274
        
1275 1276 1277
                if      (mrst)                                                           datascope_incoming_run[0] <= 0;
                else if (datascope_incoming_start || datascope_receive_fis)              datascope_incoming_run[0] <= 1;
                else if (datascope_incoming_cntr == 0)                                   datascope_incoming_run[0] <= 0;
1278
        
1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301
                if      (mrst || datascope_incoming_start)                               datascope_incoming_run[1] <= 0;
                else if (datascope_incoming_run[0] && datascope_incoming_started)        datascope_incoming_run[1] <= 1;
                else if (datascope_incoming_run[2])                                      datascope_incoming_run[1] <= 0;
                
                if      (mrst || datascope_incoming_start)                               datascope_incoming_run[2] <= 0;
                else if (datascope_incoming_run[1] && datascope_incomining_preend)       datascope_incoming_run[2] <= 1;
                else if (datascope_incoming_cntr == 0)                                   datascope_incoming_run[2] <= 0;
                
                if      (mrst || !datascope_incoming_run[2] ||
                                  datascope_incoming_start ||
                                  datascope_receive_fis)                                 datascope_incoming_cntr <= DATASCOPE_INCOMING_POST;
                else if (|datascope_incoming_cntr)                                       datascope_incoming_cntr <=  datascope_incoming_cntr - 1;
                
            end    
            
            assign datascope_clk = mclk;
            assign datascope_waddr = last_jump_addr;
            assign datascope_we = &datascope_new_jump;
            assign datascope_di = {2'h3, fsnd_pCmdToIssue,  xfer_cntr_zero, 2'b0, last_jump_addr[9:0],datascope_jump_cntr};  
          always @(posedge mclk) begin
                if      (mrst)                                      datascope_run[0] <= 0;
                else if (fsnd_cfis_xmit)                            datascope_run[0] <= 1;
                else if (h2d_valid && h2d_ready && (h2d_type == 2)) datascope_run[0] <= 0;
1302
        
1303 1304 1305 1306 1307
                if      (mrst)                                                             datascope_link_run <= 0;
                else if (datascope_is_state_send_ready && !datascope_was_state_send_ready) datascope_link_run <= 1; // state_send_sof
                else if (datascope_is_state_idle)                                          datascope_link_run <= 0; // state_idle
                
                datascope_was_state_send_ready <= datascope_is_state_send_ready;
1308
        
1309 1310 1311 1312 1313 1314 1315 1316 1317 1318
                
                datascope_run[1] <= datascope_run[0];
                
                
                
                if      (mrst)           datascope_id <= 0;
                else if (fsnd_cfis_xmit) datascope_id <=  datascope_id + 1;
                
            end
        `endif // DATASCOPE_FIS_DATA
1319
    
1320 1321 1322 1323
    `endif // DATASCOPE_V1   
    
`endif  // USE_DATASCOPE   
endmodule
1324

1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335
module datascope_timing #(
        parameter ADDRESS_BITS = 10, // for datascope
        parameter FIS_LEN = 5        // Record this number of DWORDS in each FIS
    )(
    input                     clk,
    input                     rst,
    // receiving time punch command and 3-bit tag
    input  [ADDRESS_BITS-1:0] soft_write_addr, 
    input              [31:0] soft_write_data, 
    input                     soft_write_en,
    
1336 1337
    input                     cfis, // to reset send counter
    
1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351
    // outgoing FISes
    input              [31:0] h2d_data,     // 32-bit data from the system memory to HBA (dma data)
    input              [ 1:0] h2d_type,     // 0 - data, 1 - FIS head, 2 - FIS END (make FIS_Last?)
    input                     h2d_valid,    // output register full
    input                     h2d_ready,    // send FIFO has room for data (>= 8? dwords)
    
    // Incoming FISes
 
// Data/type FIFO, device -> host
    input              [31:0] d2h_data,    // FIFO output data
    input              [ 1:0] d2h_type,    // 0 - data, 1 - FIS head, 2 - R_OK, 3 - R_ERR
    input                     d2h_valid,   // Data available from the transport layer in FIFO                
    input                     d2h_ready,   // This module or DMA consumes DWORD
    
1352 1353
    input                     debug_link_send_data, // @posedge mclk (sata_clk, 75MHz)  - last symbol was data output (to count sent out)
    input                     debug_link_dmatp,     // link received DMATp from device
1354
    input                     irq,                  // system irq
1355 1356 1357 1358 1359
    output                        datascope_clk,
    output reg [ADDRESS_BITS-1:0] datascope_waddr,
    output                        datascope_we,
    output reg             [31:0] datascope_di
    );
1360

1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373
`include "includes/ahci_localparams.vh" // @SuppressThisWarning VEditor : Unused localparams
    reg                 [2:0] punch_tag;
    wire                      write_tag_w = soft_write_en && (soft_write_addr[ADDRESS_BITS-1:0] == HBA_PORT__PunchTime__TAG__ADDR);
    reg                       pend_punch_time;
    wire                      write_punch_time = pend_punch_time && !fis_start && !fis_run && !fis_run_d;
    reg                       fis_run;
    reg                       fis_run_d;
    reg                       fis_we; // recording FIS data (until end or max len)
    reg                [12:0] fis_len;
    reg                [12:0] fis_left;
    reg                [31:0] fis_data;
    reg                [27:0] cur_time;
    reg                       was_h2d_last;
1374 1375 1376
    reg                       h2d_ready_d; // delayed h2d_ready to count 1->0 transitions
    reg                [ 7:0] h2d_nready_cntr; // count (infrequent) events when h2d FIFO turns off ready 
//    reg                       
1377 1378 1379 1380 1381 1382 1383
    
    wire                      fis_start = (h2d_valid && h2d_ready && (h2d_type == 1)) ||
                                          (d2h_valid && d2h_ready && (d2h_type == 1));
    wire                      fis_end =   (d2h_valid? (d2h_valid && d2h_ready && d2h_type[1]): was_h2d_last);
//    wire                      fis_end_we = (fis_left == 0) || fis_end;

    wire                      pre_we_w =  fis_run && (d2h_valid?(d2h_valid && d2h_ready):(h2d_valid && h2d_ready));
1384 1385 1386 1387 1388 1389 1390
    
    reg                       fis_run_d2;
    reg                       fis_run_d3;
    reg                       fis_run_d4; // to read non 0x39 d2h fis
    reg                       fis_run_d5; // number of dwords sent by link a s data symbols
//  reg                       fis_first;
    reg                       data_fis;
1391
    reg                       pre_we_r;                                      
1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412
    reg                       we_r;
    
    wire                      inc_dw_cntr =  fis_run && (d2h_valid?(d2h_ready && (d2h_type == 0)):(h2d_valid && h2d_ready));
    
    wire is_cfis_w = h2d_valid && (h2d_data[ 7: 0] == 8'h27) && // valid @ fis_start
                                 ((h2d_data[23:16] == 8'h25) || // Read DMA Extended
                                  (h2d_data[23:16] == 8'h35) || // Write DMA Extended
                                  (h2d_data[23:16] == 8'hC8) || // Read DMA
                                  (h2d_data[23:16] == 8'hCA));   // Write DMA
    reg  is_cfis_r;                                               
    reg                [23:0] last_dma_cmd;
    reg                       set_dma_count;                                      
    reg                [21:0] dw_count;
    wire                [7:0] fis_data_w = d2h_valid ? d2h_data[7:0]