ahci_top.v 77.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*******************************************************************************
 * Module: ahci_top
 * Date:2016-01-09  
 * Author: Andrey Filippov     
 * Description: Top module of the AHCI implementation
 * 
 * Copyright (c) 2016 Elphel, Inc .
 * 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/> .
 *******************************************************************************/
`timescale 1ns/1ps

module  ahci_top#(
Andrey Filippov's avatar
Andrey Filippov committed
24 25
    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
26 27
//    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
28 29
    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)
30 31 32
    parameter RESET_TO_FIRST_ACCESS = 1, // keep port reset until first R/W any register by software
    parameter FREQ_METER_WIDTH =     12
    
33 34
)(
    input             aclk,    // clock - should be buffered
35 36
    input             arst,    // @aclk sync reset, active high
    input             mclk,    // SATA system clock (current 75MHz for SATA2)
37
    input             mrst,    // reset in mclk clock domain (after SATA PLL is on)
38
    // async reset for SATA (mrst will be response to it)
39
    output            hba_arst,          // hba async reset (currently does ~ the same as port reset)
Andrey Filippov's avatar
Andrey Filippov committed
40 41
    output            port_arst,         // port0 async set by software (does not include arst)
    output            port_arst_any,     // port0 async set by software and by arst
42 43
    input             hclk,    // AXI HP interface clock for 64-bit DMA (current - 150MHz
    input             hrst,    // reset in hclk clock domain
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
// 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
60
// AXI PS Master GP0: Write response
61 62 63 64 65 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
    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
97
    input             afi_wready,  // @ SuppressThisWarning VEditor unused - used FIF0 level
98 99 100 101 102 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
    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,
133 134 135 136 137 138 139 140 141 142 143 144 145
    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           
146 147 148
    output             d2h_ready,   // This module or DMA consumes DWORD
    
    // communication with transport/link/phys layers
149 150
//    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
151
    input              xmit_ok,      // FIS transmission acknowledged OK
152
    input              xmit_err,     // Error during sending of a FIS
153
    input              syncesc_recv, // These two inputs interrupt transmit
154
    output             pcmd_st_cleared, // bit was cleared by software    
155
    output             syncesc_send,  // Send sync escape
156
    input              syncesc_send_done, // "SYNC escape until the interface is quiescent..."
157
    output             comreset_send,     // Not possible yet?
158 159
    input              cominit_got,
    output             set_offline, // electrically idle
160
    input              x_rdy_collision, // X_RDY/X_RDY collision on interface 
161
    
162 163
    output             send_R_OK,    // Should it be originated in this layer SM?
    output             send_R_ERR,
164 165 166 167 168 169 170 171 172 173 174
    
    // 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  
175
    input              serr_EE,   // RWC: Internal error (such as elastic buffer overflow or primitive mis-alignment)
176 177 178 179 180 181 182 183 184 185
    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
    
    
186

187
    output             irq, // CPU interrupt request
188 189 190 191 192 193 194 195 196 197
    
`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
198 199 200 201 202 203 204 205
`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    
206
    input  [FREQ_METER_WIDTH - 1:0] xclk_period,      // relative (to 2*clk) xclk period
207 208
    input       [31:0] debug_in_phy,
    input       [31:0] debug_in_link
209
    
210 211
    
);
212 213 214 215 216 217 218 219
`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    

220 221 222 223
// 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)
224 225 226
    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
227
// 2. HBA R/W registers, use hba clock
228
//    wire                    hba_rst;
229 230 231
    wire                    regs_we_acs;
//    wire              [1:0] regs_re_fsm;
    wire             [31:0] regs_din_from_acs; // from fsm
232 233
    wire                    regs_we_freceive;
    wire              [1:0] regs_re_ftransmit; // [0] - re, [1] - regen
234
    wire [ADDRESS_BITS-1:0] regs_saddr; // read/write adderss from ahci_fsm
235 236
    wire [ADDRESS_BITS-1:0] regs_waddr;
    wire [ADDRESS_BITS-1:0] regs_raddr;
237
    wire             [31:0] regs_din_from_freceive;
238
    wire             [31:0] regs_dout;
239 240 241 242 243 244

    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
245 246
    wire [ADDRESS_BITS-1:0] regs_addr = ({ADDRESS_BITS{regs_we_freceive}} & regs_waddr) |
                                        ({ADDRESS_BITS{regs_re_ftransmit[0]}} & regs_raddr) |
247
                                        ({ADDRESS_BITS{regs_we_acs}} & regs_saddr);
248
                                        
249 250 251 252 253 254

/*
    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);
*/                                        
255
    wire             [31:0] regs_din =  ({32{regs_we_freceive}} & regs_din_from_freceive) |
256 257
                                        ({32{regs_we_acs}} &      regs_din_from_acs);
//    wire              [1:0] regs_re = regs_re_ftransmit | regs_re_fsm; // [0] - re, [1] - regen
258
    
259
    
260 261
//---------------------    

262 263
//    wire             [31:7] ctba; // input[31:7] 
    wire                    ctba_ld; // input
264 265
    wire             [15:0] prdtl; // input[15:0]
     
266 267 268
    wire                    dev_wr; // input
    wire                    dma_cmd_start; // input
    wire                    dma_prd_start; // input
269
    wire                    dma_cmd_abort_xmit; // input
270
    wire                    dma_cmd_abort_fsm;  // abort from FSM (also from ahci_fis_transmit)
271
        
272 273 274 275 276
// 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
    
277
    
278 279
    wire             [ 3:0] axi_wr_cache_mode; // input[3:0] 
    wire             [ 3:0] axi_rd_cache_mode; // input[3:0] 
280
    wire                    set_axi_cache_mode; // input (both axi_wr_cache_mode and axi_rd_cache_mode)
281 282 283 284
    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 
285
///    wire                    dma_prd_done; // output (finished next prd)
286 287
    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
288
    wire                    dma_cmd_busy; // output reg (DMA engine is processing PRDs)
289
    wire                    dma_cmd_done; // output (last PRD is over)
290 291 292 293 294

    wire                    dma_abort_busy;
    wire                    dma_abort_done;
    wire                    axi_mismatch;
    
295 296 297
    wire             [31:0] dma_dout;    // output[31:0] 
    wire                    dma_dav; // output
    wire                    dma_re;      // input
298 299
    wire                    last_h2d_data;// when active and no new data for 2 clocks - that was the last one
    
300 301
    wire                    dma_in_ready; // output
    wire                    dma_we;      // input
302 303 304
    wire                    dma_extra_din;    // all DRDs are transferred to memory, but FIFO has some data. Valid when transfer is stopped
    
    
305
// ---------------------------------------
306 307 308
    // fsm <-> ahc_fis_receive
    // fsm ->
    wire                    frcv_first_vld;
309 310 311 312
    // 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
    
313 314 315 316 317 318 319 320 321 322
    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
323 324
    wire                    frcv_update_pio;    // update PxTFD.STS and PxTFD.ERR from pio_* (entry PIO:Update)
    
325 326
    wire                    frcv_update_prdbc;  // update PRDBC in registers
    wire                    frcv_clear_bsy_drq; // clear PxTFD.STS.BSY and PxTFD.STS.DRQ, update
327 328
    wire                    frcv_clear_bsy_set_drq; // clear PxTFD.STS.BSY and sets PxTFD.STS.DRQ, update
    
329 330 331
    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
332 333
    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
334
    wire                    frcv_clear_xfer_cntr; // Clear pXferCntr to 0
335 336 337 338 339 340 341
    
    // 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
342 343
    wire                    frcv_extra;         // DMA all transferred, but some data is still in left. . Does not deny frcv_ok
    
344
    wire                    frcv_set_update_sig; // when set, enables get_sig (and resets itself)
345 346
///    wire                    frcv_pUpdateSig;     // state variable
///    wire                    frcv_sig_available;  // signature data available
347 348
    wire                    frcv_update_sig;        // update signature

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

    // fsm <-> ahc_fis_transmit
    // Command pulses to execute states fsm -> ahc_fis_transmit
372
    wire                    fsnd_fetch_cmd;    // Enter p:FetchCmd, fetch command header (from the register memory, prefetch command FIS)
373 374
                                               // 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)
375 376 377
    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
378 379
    // responses fsm <- ahc_fis_transmit
    wire                    fsnd_done;
380
///    wire                    fsnd_busy;
381 382 383 384
    // 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
385
    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)
386 387 388 389 390 391
    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
392
///    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
393 394 395

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

396 397
    wire                    was_hba_rst; 
    wire                    was_port_rst; 
398

399
    // signals between ahci_fsm and ahci_ctrl_stat
400
///    wire                          update_regs_pending;
401 402
    wire                          update_all_regs;
    wire                          update_regs_busy; // valid same cycle as update_all_regs
403

404 405 406
///    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
407

408
    
409
    // these following individual signals may be unneded - use update_all_regs -> update_regs_busy
410 411 412 413 414 415
//    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;
416 417

// PxCMD
418 419 420
//    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)
421 422
    wire                          pcmd_cr_set;    // command list run set
    wire                          pcmd_cr_reset;  // command list run reset
423
//    wire                          pcmd_fr;        // ahci_fis_receive:get_fis_busy - use frcv_busy
424 425 426

    wire                          pcmd_fre0;      // FIS enable copy to memory
    wire                          pcmd_fre = pcmd_fre0 || 1;     // FIS enable copy to memory
427 428 429
//    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
430
    wire                          pcmd_st;        // current value
431
    wire                          pfsm_started;   // H: FSM done, P: FSM started (enable sensing pcmd_st_cleared)
432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448
//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
449
    wire                          serr_diag_X; // value of PxSERR.DIAG.X
450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468

     
    
// 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
469 470
    wire                    [3:0] ssts_det;          // current value of PxSSTS.DET
    
471 472
 // SCR2:SControl (written by software only)
    wire                    [3:0] sctl_det;          // Device detection initialization requested
473 474
    wire                          sctl_det_changed;  // Software had written new value to sctl_det
    wire                          sctl_det_reset;    // clear sctl_det_changed
475 476 477
    
    wire                          pxci0_clear;       // PxCI clear
    wire                          pxci0;             // pxCI current value
478
    wire                          hba_rst_done;      // HBA reset done - clear GHC.HR (and some other regs)
479
    
480 481 482
    wire                          comreset_send0; // just disabling it
    
    
483
    wire                    [9:0] last_jump_addr;
484 485
    wire                   [31:0] debug_dma;
    wire                   [31:0] debug_dma1;
Andrey Filippov's avatar
Andrey Filippov committed
486
    wire                   [31:0] debug_dma_h2d;
487 488 489 490

    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

491 492 493
    
    assign comreset_send = comreset_send0 && 0;
    
494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511
    // 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
*/    
512 513


514 515 516 517 518 519 520 521 522
    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
523

524 525 526 527 528
        .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
529

530 531
        .phy_ready                (phy_ready),         // input
        .syncesc_send             (syncesc_send),      // output
532
        .comreset_send            (comreset_send0),     // output
533
        .syncesc_send_done        (syncesc_send_done), // input
534 535
        .cominit_got              (cominit_got),       // input
        .set_offline              (set_offline),       // output
536
//        .x_rdy_collision          (x_rdy_collision),   // input 
537 538 539
        
        .send_R_OK                (send_R_OK),         // output
        .send_R_ERR               (send_R_ERR),        // output
540
        
541
///        .update_pending           (update_regs_pending),// input
542 543
        .update_all               (update_all_regs),   // output
        .update_busy              (update_regs_busy),  // input
544 545 546 547 548 549 550 551 552 553 554 555
///        .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
556 557
        .pcmd_cr_set              (pcmd_cr_set),       // output
        .pcmd_cr_reset            (pcmd_cr_reset),     // output
558 559
//        .pcmd_fr                  (pcmd_fr),           // output
//        .pcmd_clear_bsy_drq       (pcmd_clear_bsy_drq),// output
560
        .pcmd_clo                 (pcmd_clo),          // input
561
//        .pcmd_clear_st            (pcmd_clear_st),     // output
562
        .pcmd_st                  (pcmd_st),           // input
563 564
        .pfsm_started             (pfsm_started),      // output
        .pcmd_st_cleared          (pcmd_st_cleared),   // input 
565 566 567 568 569 570 571 572 573 574 575 576
        .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
577
        .serr_diag_X              (serr_diag_X),       // input
578 579 580 581 582 583 584 585 586 587 588 589 590
        .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
591
        .ssts_det                 (ssts_det),          // input[3:0]
592 593
///        .sctl_ipm                 (sctl_ipm),          // input[3:0] 
///        .sctl_spd                 (sctl_spd),          // input[3:0] 
594
        .sctl_det                 (sctl_det),          // input[3:0] 
595 596
        .sctl_det_changed         (sctl_det_changed),  // input 
        .sctl_det_reset           (sctl_det_reset),    // output
597
        .hba_rst_done             (hba_rst_done),      // output
598 599
        .pxci0_clear              (pxci0_clear),       // output
        .pxci0                    (pxci0),             // input
600

601
///        .dma_prd_done             (dma_prd_done),       // input
602 603 604
        .dma_prd_irq_clear        (dma_prd_irq_clear),  // output
        .dma_prd_irq_pend         (dma_prd_irq_pend),   // input
        
605
        .dma_cmd_busy             (dma_cmd_busy),       // input
606
///        .dma_cmd_done             (dma_cmd_done),       // input
607
        .dma_cmd_abort            (dma_cmd_abort_fsm),  // output
608 609 610
        .dma_abort_done           (dma_abort_done),     // input
        .fis_first_invalid        (frcv_first_invalid),// input
        .fis_first_flush          (frcv_first_flush),  // output
611
        
612 613 614
        .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
615

616 617 618 619 620 621 622 623 624 625 626 627 628
        .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
629
        
630 631 632 633
        .set_update_sig           (frcv_set_update_sig),// output
///        .pUpdateSig            (frcv_pUpdateSig),    // input
///        .sig_available         (frcv_sig_available), // input
        .update_sig               (frcv_update_sig),    // output
634
        
635 636 637 638 639 640 641 642 643 644 645
        .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)
646
//      .decr_DXC_dw     (data_out_dwords),    // output[11:2] **** Probably not needed
647
        .pxcmd_fre                ( pcmd_fre), // input
648 649 650 651
        .pPioXfer                 (pPioXfer),           // input      
        .tfd_sts                  (tfd_sts),            // input[7:0] 
///        .tfd_err            (tfd_err),            // input[7:0] 
        .fis_i                    (fis_i),              // input
652
///        .sdb_n           (sdb_n),              // input
653
        .dma_a                    (dma_a),              // input
654
///        .dma_d           (dma_d),              // input
655 656
        .pio_i                    (pio_i),              // input
        .pio_d                    (pio_d),              // input
657 658 659
///        .sactive0        (sactive0),            // input
///        .pio_es          (pio_es),             // input[7:0] 
///        .xfer_cntr       (xfer_cntr[31:2]),    // input[31:2] 
660
        .xfer_cntr_zero           (xfer_cntr_zero),     // input
661
        
662 663 664 665 666
        .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
667
///        .xmit_busy       (fsnd_busy),          // input
668 669
        .clearCmdToIssue          (fsnd_clearCmdToIssue),// output // From CFIS:SUCCESS 
        .pCmdToIssue              (fsnd_pCmdToIssue),   // input
670
        .dx_err                   (fsnd_dx_err),        // input[2:0] 
671
///        .ch_prdtl        (prdtl),              // input[15:0] 
672 673 674 675 676 677
        .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
678 679
///        .ch_cfl          (fsnd_ch_cfl),        // input[4:0] 
///        .dwords_sent     (data_out_dwords)     // input[11:0] ????
680
        .unsolicited_en           (unsolicited_en),     // input
681
        .last_jump_addr           (last_jump_addr)
682
    );
683

684 685 686
wire debug_data_in_ready;       // output
wire debug_fis_end_w;           // output
wire[1:0] debug_fis_end_r;      // output[1:0] 
687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704
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;
705

706 707 708 709 710
    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
711

712
    axi_ahci_regs #(
Andrey Filippov's avatar
Andrey Filippov committed
713 714 715
        .ADDRESS_BITS          (ADDRESS_BITS),
        .HBA_RESET_BITS        (HBA_RESET_BITS),
        .RESET_TO_FIRST_ACCESS (RESET_TO_FIRST_ACCESS)
716 717 718 719 720 721 722 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
    ) 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
752
        .hba_arst         (hba_arst),        // output // does not include arst
Andrey Filippov's avatar
Andrey Filippov committed
753
        .port_arst_any    (port_arst_any),   // async set by arst
754
        .port_arst        (port_arst),       // output // does not include arst
755
        .hba_clk          (mclk),            // input
756
        .hba_rst          (mrst),            // input   // deasserted when mclk is stable
757 758 759 760
        .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] 
761 762 763 764
        .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 
765 766
        .afi_wcache       (axi_wr_cache_mode),// output[3:0] reg 
        .afi_rcache       (axi_rd_cache_mode),// output[3:0] reg 
767 768
        .afi_cache_set    (set_axi_cache_mode), // output
        .was_hba_rst      (was_hba_rst),     // output 
769
        .was_port_rst     (was_port_rst),    // output 
770 771 772 773 774 775 776 777
        .debug_in0        ({ 2'b0,
                             was_good_bad_prev,
                             debug_d2h_length_prev[12:0],
                             2'b0,
                             was_good_bad,
                             debug_d2h_length[12:0]
                             }),
                             
778 779
//        .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]
780
        .debug_in1        ({debug_in_link[15:8],
781
                            debug_dma1[23:0]}),      // debug_in_link),   // input[31:0]
Andrey Filippov's avatar
Andrey Filippov committed
782
        .debug_in2        (debug_in_phy),    // input[31:0]     // debug from phy/link
783
//        .debug_in3        ({22'b0, last_jump_addr[9:0]}) // input[31:0]// Last jump address in the AHDCI sequencer
784
        .debug_in3        ({debug_in_link[7:0],
785
                            frcv_busy,frcv_ok, // 2'b0,
786
`ifdef USE_DATASCOPE
787
                             datascope_waddr[9:0],
788 789 790
`else
                             10'b0,
`endif                             
791 792
                            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
793 794 795 796 797 798 799 800 801 802
`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    
        
        
803 804 805 806
`ifdef USE_DATASCOPE
        ,.datascope_clk   (datascope_clk),   // input
        .datascope_waddr  (datascope_waddr), // input[9:0] 
        .datascope_we     (datascope_we),    // input
807 808 809 810 811 812
        .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] 
813
`endif        
814
///        .debug_in         (debug_in[31:0])
815
    );
816 817 818
    ahci_ctrl_stat #(
        .ADDRESS_BITS            (ADDRESS_BITS)
    ) ahci_ctrl_stat_i (
819 820 821 822 823 824 825 826 827 828
        .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 
829
        .update_pending          (), /// update_regs_pending),     // output
830 831
        .update_all              (update_all_regs),         // input
        .update_busy             (update_regs_busy),        // output
832 833 834 835 836 837 838 839 840 841
///        .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
842
        .update_ghc              (1'b0), // update _GHC_GHC,          // input
843
        
Andrey Filippov's avatar
Andrey Filippov committed
844
//        .pcmd_clear_icc          (1'b0), // pcmd_clear_icc),          // input
845
        .pcmd_esp                (pcmd_esp),                // input
846
        .pcmd_cr                 (), //pcmd_cr),                 // output
847 848
        .pcmd_cr_set             (pcmd_cr_set),             // input
        .pcmd_cr_reset           (pcmd_cr_reset),           // input
849
        .pcmd_fr                 (frcv_busy),               // input
850
        .pcmd_fre                (pcmd_fre0),               // output
851
        .pcmd_clear_bsy_drq      (frcv_clear_bsy_drq),      // input
852
        .pcmd_clo                (pcmd_clo),                // output
853
        .pcmd_clear_st           (1'b0), // pcmd_clear_st),           // input
854
        .pcmd_st                 (pcmd_st),                 // output
855 856
        .pfsm_started            (pfsm_started),            // input
        .pcmd_st_cleared         (pcmd_st_cleared),         // output reg 
857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875
        .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
876
        .serr_EE                 (serr_EE),                 // input
877 878 879 880 881
        .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
882
        .serr_diag_X             (serr_diag_X),             // output
883 884 885 886 887 888 889 890 891 892 893 894 895
        .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
896
        .ssts_det                (ssts_det),                // output[3:0]
897 898
        .sctl_ipm                (sctl_ipm),                // output[3:0] reg 
        .sctl_spd                (sctl_spd),                // output[3:0] reg 
899 900 901
        .sctl_det                (sctl_det),                // output[3:0] reg
        .sctl_det_changed        (sctl_det_changed),        // output reg 
        .sctl_det_reset          (sctl_det_reset),          // input
902 903
        .pxci0_clear             (pxci0_clear),             // input
        .pxci0                   (pxci0),                   // output
904
        .hba_reset_done          (hba_rst_done),            // input
905
        .unsolicited_en          (unsolicited_en),          // output
906
        .irq                     (irq)                      // output reg 
907
    );
908 909

    ahci_dma ahci_dma_i (
910 911 912 913
        .mrst                  (mrst),          // input
        .hrst                  (hrst),          // input
        .mclk                  (mclk),          // input
        .hclk                  (hclk),          // input
914 915
//        .ctba                  (regs_dout[31:7]),// input[31:7] 
        .ctba                  (regs_dout[31:4]),// input[31:4] 
916 917 918
        .ctba_ld               (ctba_ld),       // input
        .prdtl                 (prdtl),         // input[15:0] 
        .dev_wr                (dev_wr),        // input
919 920
        .cmd_start             (dma_cmd_start), // input
        .prd_start             (dma_prd_start), // input
921
        .cmd_abort             (dma_cmd_abort_xmit || dma_cmd_abort_fsm), // input
922 923
        .axi_wr_cache_mode     (axi_wr_cache_mode), // input[3:0] 
        .axi_rd_cache_mode     (axi_rd_cache_mode), // input[3:0] 
924 925
        .set_axi_wr_cache_mode (set_axi_cache_mode), // input
        .set_axi_rd_cache_mode (set_axi_cache_mode), // input
926 927
        .ct_busy               (dma_ct_busy),   // output reg 
        .ct_addr               (dma_ct_addr),   // input[4:0] 
928
        .ct_re                 (dma_ct_re),     // input[1:0]
929
        .ct_data               (dma_ct_data),   // output[31:0] reg 
930
        .prd_done              (), /// dma_prd_done),  // output
931 932 933 934
        
        .prd_irq_clear         (dma_prd_irq_clear),// input
        .prd_irq_pend          (dma_prd_irq_pend), // output reg
        
935
        .cmd_busy              (dma_cmd_busy), // dma_cmd_busy),  // output reg Some data to transmit!
936
        .cmd_done              (dma_cmd_done),  // output
937 938 939
        .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
940 941 942
        .sys_out               (dma_dout),      // output[31:0] 
        .sys_dav               (dma_dav),       // output
        .sys_re                (dma_re),        // input
943
        .last_h2d_data         (last_h2d_data), // output
944 945 946
        .sys_in                (d2h_data),      // input[31:0] 
        .sys_nfull             (dma_in_ready),  // output
        .sys_we                (dma_we),        // input
947
        .extra_din             (dma_extra_din), // output reg
948 949 950 951 952 953 954 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
        .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] 
991 992 993
        .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
994
        ,.debug_dma_h2d    (debug_dma_h2d)
995 996 997
    );

    ahci_fis_receive #(
998
        .ADDRESS_BITS      (ADDRESS_BITS)
999
    ) ahci_fis_receive_i (
1000 1001
        .hba_rst           (mrst),                   // input
        .mclk              (mclk),                   // input
1002
        .pcmd_st_cleared   (pcmd_st_cleared),        // input
1003
        .fis_first_vld     (frcv_first_vld),         // output reg 
1004 1005
        .fis_first_invalid (frcv_first_invalid),     // output
        .fis_first_flush   (frcv_first_flush),       // input
1006

1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019
        .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
1020

1021 1022 1023
        .dma_prds_done     (dma_cmd_done),           // input
        .fis_extra         (frcv_extra),             // output

1024
        .set_update_sig    (frcv_set_update_sig),    // input
1025 1026
        .pUpdateSig        (), /// frcv_pUpdateSig),        // output
        .sig_available     (), ///frcv_sig_available),     // output reg 
1027
        .update_sig        (frcv_update_sig),        // input
1028 1029
        
        .update_err_sts    (frcv_update_err_sts),    // input
1030 1031
        .update_pio        (frcv_update_pio),        // input  update PxTFD.STS and PxTFD.ERR from pio_* (entry PIO:Update)
        
1032
        .update_prdbc      (frcv_update_prdbc),      // input
1033 1034
        .clear_prdbc       (fsnd_fetch_cmd),         // input save resources - clear prdbc for every commnad
        
1035
        .clear_bsy_drq     (frcv_clear_bsy_drq),     // input
1036 1037
        .clear_bsy_set_drq (frcv_clear_bsy_set_drq), // input
        
1038 1039 1040
        .set_bsy           (frcv_set_bsy),           // input
        .set_sts_7f        (frcv_set_sts_7f),        // input
        .set_sts_80        (frcv_set_sts_80),        // input
1041
        .clear_xfer_cntr (frcv_clear_xfer_cntr),     // input Clear pXferCntr
1042 1043
        .decr_dwcr         (frcv_decr_dwcr),         // input
        .decr_dwcw         (frcv_decr_dwcw),         // input
1044 1045 1046
        .decr_DXC_dw       (data_out_dwords),        // input[11:2]
        .pcmd_fre          (pcmd_fre),               // input
         
1047
        .pPioXfer          (pPioXfer),               // output reg 
1048
        
1049
        .tfd_sts           (tfd_sts),                // output[7:0] 
1050
        .tfd_err           (), /// tfd_err),                // output[7:0] 
1051
        .fis_i             (fis_i),                  // output reg 
1052
        .sdb_n             (), /// sdb_n),                  // output reg 
1053
        .dma_a             (dma_a),                  // output reg 
1054
        .dma_d             (), /// dma_d),                  // output reg 
1055 1056
        .pio_i             (pio_i),                  // output reg 
        .pio_d             (pio_d),                  // output reg 
1057 1058
        .pio_es            (), /// pio_es),                 // output[7:0] reg 
        .sactive0          (), /// sactive0),               // output reg 
1059 1060
        .xfer_cntr         (xfer_cntr[31:2]),        // output[31:2] 
        .xfer_cntr_zero    (xfer_cntr_zero),         // output reg
1061
        .data_in_dwords    (), /// data_in_dwords),         // output[11:0] 
1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072
         
        .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
1073 1074 1075 1076 1077
        
        ,.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] 
1078
    );
1079 1080
wire ahci_fis_transmit_busy;
wire [9:0] xmit_dbg_01;
1081
    ahci_fis_transmit #(
1082 1083 1084 1085
        .PREFETCH_ALWAYS  (PREFETCH_ALWAYS),
        .READ_REG_LATENCY (READ_REG_LATENCY),
        .READ_CT_LATENCY  (READ_CT_LATENCY),
        .ADDRESS_BITS     (ADDRESS_BITS)
1086
    ) ahci_fis_transmit_i (
1087 1088
//        .hba_rst           (mrst),                 // input TODO: Reset when !PxCMD.ST? pcmd_st
        .hba_rst           (mrst || !pcmd_st),     // input TODO: Reset when !PxCMD.ST? pcmd_st
1089
        .mclk              (mclk),                 // input
Andrey Filippov's avatar
Andrey Filippov committed
1090
        .pcmd_st_cleared   (pcmd_st_cleared),      // input
1091 1092
        .fetch_cmd         (fsnd_fetch_cmd),       // input
        .cfis_xmit         (fsnd_cfis_xmit),       // input
1093
        .dx_xmit           (fsnd_dx_xmit),         // input
1094
        .atapi_xmit        (fsnd_atapi_xmit),      // input
1095
        
1096
        .done              (fsnd_done),            // output reg 
1097
        .busy              (ahci_fis_transmit_busy), /// fsnd_busy),            // output reg 
1098 1099
        .clearCmdToIssue   (fsnd_clearCmdToIssue), // input
        .pCmdToIssue       (fsnd_pCmdToIssue),     // output
1100
        .xmit_ok           (xmit_ok),              // input
1101
        .xmit_err          (xmit_err),             // input
1102 1103
        .syncesc_recv      (syncesc_recv),         // input
        .xrdy_collision    (x_rdy_collision),      // input
1104 1105 1106 1107 1108 1109 1110 1111
        .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
1112
        .ch_cfl            (), /// fsnd_ch_cfl),          // output[4:0] 
1113 1114 1115 1116 1117 1118

        .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] 
1119
        .xfer_cntr_zero    (xfer_cntr_zero),       // input 
1120 1121 1122 1123 1124
        .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 
1125
        .dma_cmd_abort     (dma_cmd_abort_xmit),   // output reg
1126 1127 1128 1129 1130 1131
        .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
1132
        .last_h2d_data     (last_h2d_data),        // input
1133 1134 1135 1136
        .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
1137
       ,.debug_01(xmit_dbg_01)
1138 1139
    );

1140
// Datascope code
1141
//`define DATASCOPE_V2
1142
// Datascope interface (write to memory that can be software-read)
1143 1144
`define DATASCOPE_FIS_DATA 1

Andrey Filippov's avatar
Andrey Filippov committed
1145 1146
`ifdef USE_DATASCOPE

1147 1148 1149 1150
    `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
1151
        
1152 1153 1154
        assign datascope_we = datascope_run[1];
        assign datascope_clk = mclk;
        assign datascope_waddr = datascope_waddr_r;
Andrey Filippov's avatar
Andrey Filippov committed
1155
        
1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166
         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
1167
    
1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182
                                 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;
1183
    
1184 1185
            if    (fsnd_cfis_xmit)          datascope_waddr_r <= 0;
            else if (datascope_we)          datascope_waddr_r <= datascope_waddr_r + 1;
1186
    
1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214
            
        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
                .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
                .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 
            );
1215
        
1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 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
        `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;
1263
        
1264 1265 1266
                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;
1267
        
1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290
                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;
1291
        
1292 1293 1294 1295 1296
                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;
1297
        
1298 1299 1300 1301 1302 1303 1304 1305 1306 1307
                
                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
1308
    
1309 1310 1311 1312
    `endif // DATASCOPE_V1   
    
`endif  // USE_DATASCOPE   
endmodule
1313

1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343
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,
    
    // 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
    
    output                        datascope_clk,
    output reg [ADDRESS_BITS-1:0] datascope_waddr,
    output                        datascope_we,
    output reg             [31:0] datascope_di
    );
1344

1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376
`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;
    
    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));
    reg                       pre_we_r;                                      
    reg                       we_r;                                      
    assign datascope_we =  we_r;
    assign datascope_clk = clk;
    
    always @ (posedge clk) begin
        was_h2d_last <= h2d_type[1] && h2d_valid && h2d_ready;
    
        if (rst) cur_time <= 0;
        else     cur_time <= cur_time + 1;
    
        if (write_tag_w) punch_tag <= soft_write_data[2:0];
1377
        
1378 1379 1380
        if      (rst)                 pend_punch_time <= 0;
        else if (write_tag_w)         pend_punch_time <= 1;
        else if (write_punch_time)    pend_punch_time <= 0;
1381
        
1382 1383 1384
        if (write_punch_time || fis_start) datascope_di <= {write_punch_time?{1'b1,punch_tag}:{3'b0,d2h_valid},cur_time};
        else if (fis_we)                   datascope_di <= fis_data;
        else if (!fis_run && fis_run_d)    datascope_di <= {19'h7fff8, fis_len};
1385
        
1386
        pre_we_r <= pre_we_w || fis_start ;
1387
    
1388
        we_r <= write_punch_time || fis_start || (fis_we ? pre_we_r : (!fis_run && fis_run_d));
1389
        
1390 1391
        if     (fis_start) fis_left <= FIS_LEN - 1;
        else if (pre_we_w) fis_left <= fis_left - 1;
1392
        
1393 1394 1395
        if      (rst)                        fis_we <= 0;
        else if (fis_start)                  fis_we <= 1;
        else if ((fis_left == 0) || fis_end) fis_we <= 0;
1396
        
1397 1398 1399 1400 1401
        if      (rst)        fis_run <= 0;
        else if (fis_start)  fis_run <= 1;
        else if (fis_end)    fis_run <= 0;

        fis_run_d <= fis_run;
1402
        
1403 1404
        if     (fis_start) fis_len <= d2h_valid? 0 : 1;
        else if (pre_we_w) fis_len <= fis_len + 1;
1405
        
1406
        if (fis_start || pre_we_w) fis_data <= d2h_valid ? d2h_data : h2d_data;
1407