The Elements of Logic Design Style

Appendix C: Sample Verilog Files for Modeling a Controller

Shing Kong

March 2001

Copyright (c) 2001 by Shing Ip Kong. All Rights Reserved.

Filed at: http://www.cs.wisc.edu/~markhill/kong/appendixC.html

Main text at: http://www.cs.wisc.edu/~markhill/kong



Appendix C: Sample Verilog Files for Modeling a Controller   $Revision: 1.1 $
-----------------------------------------------------------------------------

/****************************************************************************
 *
 * File Name: trans_defs.v
 *
 * Comment: Definitions for the Transport Layer
 *
 * Author: Shing Kong
 * Creation Date: 3/21/2001
 *
 * $Source: /proj/gemini/cvs_root/P2002/Notes/Style/appendixC,v $
 * $Date: 2001/12/06 21:49:07 $
 * $Revision: 1.1 $
 *
 *===========================================================================
 * Copyright (c) 2001 by Shing Ip Kong.  All Rights Reserved.
 ****************************************************************************/
/*
 * $Id: appendixC,v 1.1 2001/12/06 21:49:07 kong Exp $
 */

/*
 * When the (Number of Unused Entries - 1) in the FIFO is less than
 * this value, declare the receive FIFO as "nearly full."
 */
`define NEARFULL	 5'd20	// Declare "nearfull" when we have 20 entries

/*
 * For the Receive engine, assert timeout if the Transport layer is
 * expecting an incoming FIS and the Link Layer has not written anything
 * into the rxfifo for `RXTIMEOUT cycles.
 *
 * For the Transmit engine, assert timeout if the Transport layer has
 * finished writing the FIS into the txfifo but the Link Layer has not
 * done anymore reading for `TXTIMEOUT cycles.
 */
`define RXTIMEOUT	10'd999
`define TXTIMEOUT	10'd999

/*
 * FIS Type: the 8-bit hex value as appeared in Byte 0 Word 0 of the FIS
 */
`define HFISREG		8'h27	// Host-to-Device (H) Register (REG)
`define DFISREG		8'h34	// Device-to-Host (D) Register (REG)
`define DFISDMAA	8'h39	// Device-to-Host (D) DMA Activate (DMAA)
`define DFISPIOS	8'h5F	// Device-to-Host (D) PIO Setup (PIOS)
`define BFISDMAS	8'h41	// Bidirectional (B) DMA Setup (DMAS)
`define BFISBISTA	8'h58	// Bidirectional (B) BIST Activate (BISTA)
// `define BFISDATA	8'h73	// Bidirectional (B) Data (DATA) FIS
`define BFISDATA	8'h46	// Changed per erata (see ktoh's 5/1's email)

/*
 * Number of 32-bit words in various FIS minus one
 *     For example, the Register (REG) Host-to-Device (H) FIS (see P.167 of
 *     of the SATA Spec, Version 1.0) has 5 words => REGHFISm1 = 5 - 1 = 4.
 */
`define NHFISREGm1	3'd4	// Host-to-Device (H) Register (REG)
`define NDFISREGm1	3'd4	// Device-to-Host (D) Register (REG)
`define NDFISPIOSm1	3'd4	// Device-to-Host (D) PIO Setup (PIOS)
`define NBFISDMASm1	3'd6	// Bidirectional (B) DMA Setup (DMAS)
`define NBFISBISTAm1	3'd2	// Bidirectional (B) BIST Activate (BISTA)

/*
 * Log 2 of the biggest number appears above.  The biggest number at this
 * point is: DMASFISBm1 = 6; so Integer (log (6)) = 3.  Notice that if this
 * number change, we need to change the "3'd" definition above as well as
 * changing the v_count3 to a differnt width counter in dtrans_ctl.v.
 */
`define log_maxfis	 3

/*
 * Define the state values and bit position for the Host's Transmit Finite
 * State machine (FSM in htran_txctl).  This FSM implements the "transmit"
 * states describes in Section 8.6 (PP. 181-197) of SATA Spec, 1.0.
 */
`define num_httxfsm	16
`define B_HTTXIDLE	 0
`define B_HTCHKTYP	 1
`define B_HTCMDFIS	 2
`define B_HTCTLFIS	 3
`define B_HTDMASTUP	 4	// Spec's HT_DMASTUPFIS
`define B_HTXMITBIS	 5
`define B_HTPIOTX2	 6	// Spec's HT_PIOOTrans2

// These states are entered via HT_CHKTYP after Transport Receiver
// decode FISs that require the Host Transport Layer to transmit.
`define B_HTPIOTX1	 7	// Spec's HT_PIOOTrans1
`define B_HTDMATX1	 8	// Spec's HT_DMAOTrans1
`define B_HTDMATX2	 9	// Spec's HT_DMAOTrans2

// The following are collectively referred to as: HT_TransStatus in the spec
`define B_HTCMDSTA	10
`define B_HTCTLSTA	11
`define B_HTDMASSTA	12
`define B_HTBISSTA	13

`define B_HTPIOTXEND	14	// Spec's HT_PIOEND
`define B_HTDMATXEND	15	// Spec's HT_DMAEND

// Host Dongle's TX FSM State Values
`define HTTXIDLE	16'h0001
`define HTCHKTYP	16'h0002
`define HTCMDFIS	16'h0004
`define HTCTLFIS	16'h0008
`define HTDMASTUP	16'h0010
`define HTXMITBIS	16'h0020
`define HTPIOTX2	16'h0040
`define HTPIOTX1	16'h0080
`define HTDMATX1	16'h0100
`define HTDMATX2	16'h0200
`define HTCMDSTA	16'h0400
`define HTCTLSTA	16'h0800
`define HTDMASSTA	16'h1000
`define HTBISSTA	16'h2000
`define HTPIOTXEND	16'h4000
`define HTDMATXEND	16'h8000

/*
 * Define the state values and bit position for the Host's Receive Finite
 * State machine (FSM in htran_rxctl).  This FSM implements the "Decompose"
 * states describes in Section 8.6 (PP. 181-197) of SATA Spec, 1.0.
 *
 * The following states are not defined in the spec:
 *     HTWAITTXID: wait for TX to return to Idle state.  This is added
 *                 so that TX and RX FSM can be partitioned cleanly.
 *     HTRXCLEAN:  clean up the mess if we receive an unknown FIS
 */
`define num_htrxfsm	15
`define B_HTRXIDLE	 0
`define B_HTRCVREG	 1	// Spec's HT_RegFIS: receive Register FIS
`define B_HTRCVDS	 2	// Spec's HT_DS_FIS: receive DMA Setup
`define B_HTRCVPS	 3	// Spec's HT_PS_FIS: receive PIO Setup
`define B_HTRCVBIST	 4
`define B_HTRCVDAC	 5	// Spec's HT_DMA_FIS: receive DMA Activate
`define B_HTPIORX1	 6	// Spec's HT_PITITrans1
`define B_HTPIORX2	 7	// Spec's HT_PITITrans2
`define B_HTDMARX	 8	// Spec's HT_DMAITrans
`define B_HTBISTTRAN1	 9
`define B_HTPIORXEND	10	// Spec's HT_PIOEND
`define B_HTDMARXEND	11	// Spec's HT_DMAEND
`define B_HTRXCLEAN	12	// Receive an unknown FIS, needs to clean up
`define B_HTTXBUSY	13
`define B_HTWAITTXID	14

// Host Dongle's RX FSM State Values
`define HTRXIDLE	15'h0001
`define HTRCVREG	15'h0002
`define HTRCVDS		15'h0004
`define HTRCVPS		15'h0008
`define HTRCVBIST	15'h0010
`define HTRCVDAC	15'h0020
`define HTPIORX1	15'h0040	// *** Debug 4/27: combine with RX2?
`define HTPIORX2	15'h0080	// *** Debug 4/27: combine with RX1?
`define HTDMARX		15'h0100
`define HTBISTTRAN1	15'h0200
`define HTPIORXEND	15'h0400
`define HTDMARXEND	15'h0800
`define HTRXCLEAN	15'h1000
`define HTTXBUSY	15'h2000
`define HTWAITTXID	15'h4000

/*
 * Define the state values and bit position for the Device's Transmit Finite
 * State machine (FSM in dtran_txctl).  This FSM implements the "transmit"
 * states describes in Section 8.7 (PP. 197-205) of SATA Spec, 1.0.
 */
`define num_dttxfsm	15
`define B_DTTXIDLE	 0
`define B_DTCHKTYP	 1
`define B_DTREGFIS	 2	// Spec's DT_RegHDFIS
`define B_DTPIOSTUP	 3	// Spec's DT_PIOSTUPFIS
`define B_DTDMASTUP	 4	// Spec's DT_DMASTUPFIS
`define B_DTDMAACT	 5	// Spec's DT_DMAACTFIS
`define B_DTXMITBIS	 6
`define B_DTDATAFIS	 7	// Spec's DT_DATAIFIS
`define B_DTDATATX	 8	// Spec's DT_DATAITrans
`define B_DTDTXEND	 9	// Spec's DT_DATAIEnd

// The following are collectively referred to as: DT_TransStatus in the spec
`define B_DTREGSTA	10
`define B_DTPIOSSTA	11
`define B_DTDMASSTA	12
`define B_DTDMAASTA	13
`define B_DTBISSTA	14

// Devcie Dongle's TX FSM State Values
`define DTTXIDLE	15'h0001
`define DTCHKTYP	15'h0002
`define DTREGFIS	15'h0004	// Spec's DT_RegHDFIS
`define DTPIOSTUP	15'h0008	// Spec's DT_PIOSTUPFIS
`define DTDMASTUP	15'h0010	// Spec's DT_DMASTUPFIS
`define DTDMAACT	15'h0020	// Spec's DT_DMAACTFIS
`define DTXMITBIS	15'h0040
`define DTDATAFIS	15'h0080	// Spec's DT_DATAIFIS
`define DTDATATX	15'h0100	// Spec's DT_DATAITrans
`define DTDTXEND	15'h0200	// Spec's DT_DATAIEnd

// The following are collectively referred to as: DT_TransStatus in the spec
`define DTREGSTA	15'h0400
`define DTPIOSSTA	15'h0800
`define DTDMASSTA	15'h1000
`define DTDMAASTA	15'h2000
`define DTBISSTA	15'h4000

/*
 * Define the state values and bit position for the Device's Receive Finite
 * State machine (FSM in dtran_rxctl).  This FSM implements the "Decompose"
 * states describes in Section 8.7 (PP. 197-210) of SATA Spec, 1.0.
 *
 * The following states are not defined in the spec:
 *     DTWAITTXID: wait for TX to return to Idle state.  This is added
 *                 so that TX and RX FSM can be partitioned cleanly.
 *     DTRXCLEAN:  clean up the mess if we receive an unknown FIS
 */
`define num_dtrxfsm	10
`define B_DTRXIDLE	 0
`define B_DTRCVREG	 1	// Spec's DT_RegHDFIS: receive Register FIS
`define B_DTRCVDMAS	 2	// Spec's DT_DAMSTUPFIS
`define B_DTRCVBIST	 3
`define B_DTRCVDFIS	 4	// spec's DT_DATAOFIS
`define B_DTRCVDATA	 5	// Spec's DT_DATAOREC
`define B_DTDEVABORT	 6	// Spec's DT_DeviceAbort
`define B_DTBISTTRAN1	 7
`define B_DTRXCLEAN	 8	// Receive an unknown FIS, needs to clean up
`define B_DTWAITTXID	 9

// Devcie Dongle's RX FSM State Values
`define DTRXIDLE	10'h001
`define DTRCVREG	10'h002	// Spec's DT_RegHDFIS: receive Register FIS
`define DTRCVDMAS	10'h004	// Spec's DT_DAMSTUPFIS
`define DTRCVBIST	10'h008
`define DTRCVDFIS	10'h010	// spec's DT_DATAOFIS
`define DTRCVDATA	10'h020	// Spec's DT_DATAOREC
`define DTDEVABORT	10'h040	// Spec's DT_DeviceAbort
`define DTBISTTRAN1	10'h080
`define DTRXCLEAN	10'h100	// Receive an unknown FIS, needs to clean up
`define DTWAITTXID	10'h200

/****************************************************************************
 *
 * File Name: dtrans_txctl.v
 *
 * Comment: Device Dongle Transport Layer controller for data transmission
 *
 * Author: Shing Kong
 * Creation Date: 3/25/2001
 *
 * $Source: /proj/gemini/cvs_root/P2002/Notes/Style/appendixC,v $
 * $Date: 2001/12/06 21:49:07 $
 * $Revision: 1.1 $
 *
 *===========================================================================
 * Copyright (c) 2001 by Shing Ip Kong.  All Rights Reserved.
 ****************************************************************************/
/*
 * $Id: appendixC,v 1.1 2001/12/06 21:49:07 kong Exp $
 */
`include "trans_defs.v"		// See ../../CommonFiles

module dtrans_txctl (
    // Outputs
    tp_acksendreg,
    tp_acksenddmaa,
    tp_acksendpios,
    tp_acksenddmas,
    tp_acksendbist,
    tp_acksenddata,
    tp_sendndfis,
    tp_senddafis,
    tp_partial,
    tp_slumber,
    tp_spdsel,
    txfsmidle,
    txokrxgo,
    wcount,
    wrtxfifo,
    sendreg,
    senddmaa,
    sendpios,
    senddmas,
    sendbista,
    senddata,

    // Inputs
    at_sendreg,
    at_senddmaa,
    at_sendpios,
    at_senddmas,
    at_sendbista,
    at_senddata,
    lk_txfsmidle,
    lk_txerror,
    r2t_waittxid,
    r2t_rxempty,
    txfull,
    txtimeout,
    txclk4x,
    tptx_reset);

    /*
     * Outputs to the Parallel ATA Interface Layer (dataif.v)
     */
    output		tp_acksendreg;
    output		tp_acksenddmaa;
    output		tp_acksendpios;
    output		tp_acksenddmas;
    output		tp_acksendbist;
    output		tp_acksenddata;

    /*
     * Outputs to the Link Layer (link.v)
     */
    output		tp_sendndfis;	// Sending a non-data FIS
    output		tp_senddafis;	// Sending a data FIS
    output		tp_partial;
    output		tp_slumber;
    output		tp_spdsel;

    /*
     * Outputs to the Transport Layer Receive Engine (dtrans_rx.v)
     */
    output		txfsmidle;
    output		txokrxgo;		// TX FSM gives RX FSM the OK

    /*
     * Outputs to the Transport Layer Datapath (dtrans_dp.v)
     */
    output [`log_maxfis-1:0]
			wcount;
    output		wrtxfifo;
    output		sendreg;
    output		senddmaa;
    output		sendpios;
    output		senddmas;
    output		sendbista;
    output		senddata;

    /*
     * Inputs from the Parallel ATA Interface Layer (dataif.v)
     * These signals must remain asserted until the FSM has changed state
     */
    input		at_sendreg;
    input		at_senddmaa;
    input		at_sendpios;
    input		at_senddmas;
    input		at_sendbista;
    input		at_senddata;

    /*
     * Inputs from the Link Layer (link.v)
     */
    input		lk_txfsmidle;	// TX FSM has returned to IDLE
    input		lk_txerror;	// Error in transmitting a FIS

    /*
     * Inputs from the Device Transport Layer Receive Engine (dtrans_rx.v)
     */
    input		r2t_waittxid;	// RX FSM waiting TX FSM to be idle
    input		r2t_rxempty;	// RX FIFO is empty

    /*
     * Inputs from the Transport Layer Transmit Datapath (dtrans_txdp.v)
     */
    input		txfull;
    input		txtimeout;

    /*
     * Reset signal and clocks
     */
    input 		txclk4x;	// 150 MHz Transmit Clock
    input 		tptx_reset;

    /*
     * Interconnections within this controller
     */
    wire [`num_dttxfsm-1:0]	next_state;
    wire [`num_dttxfsm-1:0]	cur_state;

    // Output of the MUXes for selecting the count limit for various states
    wire [`log_maxfis-1:0]	num_regpio;
    wire [`log_maxfis-1:0]	num_dmabis;
    wire [`log_maxfis-1:0]	count_limit;

    wire			count_enable;
    wire			count_full;

    /*
     * Next State Logic and the State Register for the finite state machine
     */
    // Next State Logic
    dtrans_txfsm dtrans_txfsm (
	// Outputs
	.next_state (next_state),

	// Inputs
	.cur_state (cur_state),
	.at_sendreg (at_sendreg),	.at_senddmaa (at_senddmaa),
	.at_sendpios (at_sendpios),	.at_senddmas (at_senddmas),
	.at_sendbista (at_sendbista),	.at_senddata (at_senddata),
	.lk_txfsmidle (lk_txfsmidle),	.lk_txerror (lk_txerror),
	.r2t_waittxid (r2t_waittxid),	.r2t_rxempty (r2t_rxempty),
	.txtimeout (txtimeout),		.expire (expire),
	.tptx_reset (tptx_reset));

    // State Register
    v_reg #(`num_dttxfsm) state_ff (cur_state, txclk4x, next_state);

    /*
     * Counter and its MUX tree to select the count limit
     * for the generation of the expire signal
     */
    v_mux2e #(`log_maxfis) regpio_mux (num_regpio,
	cur_state[`B_DTPIOSTUP], `NDFISREGm1, `NDFISPIOSm1);
    v_mux2e #(`log_maxfis) dmabis_mux (num_dmabis,
	cur_state[`B_DTXMITBIS], `NBFISDMASm1, `NBFISBISTAm1);
    v_mux2e #(`log_maxfis) cntlmt_mux (count_limit,
	(cur_state[`B_DTXMITBIS] | cur_state[`B_DTDMASTUP]),
	num_regpio, num_dmabis);

    assign count_enable = cur_state[`B_DTREGFIS] | cur_state[`B_DTPIOSTUP] |
	cur_state[`B_DTXMITBIS] | cur_state[`B_DTDMASTUP];
    v_countN #(`log_maxfis) expire_count (
        .count_out (wcount),
	.count_enable (count_enable),
        .clk (txclk4x),
        .reset (tptx_reset | expire));

    v_comparator #(`log_maxfis) expire_cmp (count_full, wcount, count_limit);
    assign expire = count_full & count_enable;

    /*
     * Output Logic for generating output signals
     */
    assign tp_acksendreg  = cur_state[`B_DTREGFIS];
    assign tp_acksenddmaa = cur_state[`B_DTDMAACT];
    assign tp_acksendpios = cur_state[`B_DTPIOSTUP];
    assign tp_acksenddmas = cur_state[`B_DTDMASTUP];
    assign tp_acksendbist = cur_state[`B_DTXMITBIS];
    assign tp_acksenddata = cur_state[`B_DTDATAFIS];

    assign tp_sendndfis = cur_state[`B_DTREGFIS] | cur_state[`B_DTPIOSTUP] |
	cur_state[`B_DTDMASTUP] | cur_state[`B_DTDMAACT] |
	cur_state[`B_DTXMITBIS];

    /*** Debug 5/7/2001: may need to fix the logic later for this ***/
    assign tp_senddafis = cur_state[`B_DTDATAFIS] | cur_state[`B_DTDATATX];

    /*** Debug 5/18/2001: need to fix the logic later ***/
    assign tp_partial = 1'b0;
    assign tp_slumber = 1'b0;
    assign tp_spdsel  = 1'b0;

    assign txfsmidle = cur_state[`B_DTTXIDLE];
    assign txokrxgo  = cur_state[`B_DTCHKTYP];

    assign wrtxfifo = ~txfull & (tp_sendndfis | tp_senddafis);

    assign sendreg   = cur_state[`B_DTREGFIS]; 
    assign senddmaa  = cur_state[`B_DTDMAACT];
    assign sendpios  = cur_state[`B_DTPIOSTUP];
    assign senddmas  = cur_state[`B_DTDMASTUP];
    assign sendbista = cur_state[`B_DTXMITBIS];
    assign senddata  = cur_state[`B_DTDATAFIS];
	
endmodule // dtrans_txctl

/****************************************************************************
 * Module dtrans_txfsm: Random logic for the transmit finite state machine
 ****************************************************************************/
module dtrans_txfsm (
    // Outputs
    next_state,

    // Inputs
    cur_state,
    at_sendreg,
    at_senddmaa,
    at_sendpios,
    at_senddmas,
    at_sendbista,
    at_senddata,
    lk_txfsmidle,
    lk_txerror,
    r2t_waittxid,
    r2t_rxempty,
    txtimeout,
    expire,
    tptx_reset);

    output [`num_dttxfsm-1:0]	next_state;

    input [`num_dttxfsm-1:0]	cur_state;

    /*
     * Inputs from the Parallel ATA Interface (dataif.v)
     */
    input		at_sendreg;
    input		at_senddmaa;
    input		at_sendpios;
    input		at_senddmas;
    input		at_sendbista;
    input		at_senddata;

    /*
     * Inputs from the Link Layer (link.v)
     */
    input		lk_txfsmidle;	// TX FSM has returned to IDLE
    input		lk_txerror;	// Error in transmitting a FIS

    /*
     * Inputs from the Device Transport Layer Receive Engine (dtrans_rx.v)
     */
    input		r2t_waittxid;	// RX FSM waiting TX FSM to be idle
    input		r2t_rxempty;	// RX FIFO is empty

    /*
     * Inputs from the Device Transport Layer Transmit Datapath (htrans_txdp.v)
     */
    input		txtimeout;	// Link layer did not empty the FIFO

    input		expire;
    input		tptx_reset;

    reg [`num_dttxfsm-1:0]	next_state;

    always @(cur_state or at_sendreg or at_senddmaa or at_sendpios or
    at_senddmas or at_sendbista or at_senddata or
    lk_txfsmidle or lk_txerror or
    r2t_waittxid or r2t_rxempty or
    txtimeout or expire or tptx_reset) begin

	if (tptx_reset) begin
	    next_state = `DTTXIDLE;
	end
	else begin
	    case (cur_state)
	    `DTTXIDLE:
		if (~r2t_rxempty) begin
		    /*
 		     * Give the receive engine higher priority
		     */
		    next_state = `DTCHKTYP;
		end
		else if (~lk_txfsmidle) begin
		    /*
		     * Do not send a new FIS until the Link Layer has
		     * finished reading the last one.
		     */
		    next_state = `DTTXIDLE;
		end
		else if (at_sendreg) begin
		    next_state = `DTREGFIS;
		end
		else if (at_sendpios) begin
		    next_state = `DTPIOSTUP;
		end
		else if (at_senddmas) begin
		    next_state = `DTDMASTUP;
		end
		else if (at_senddmaa) begin
		    next_state = `DTDMAACT;
		end
		else if (at_sendbista) begin
		    next_state = `DTXMITBIS;
		end
		else if (at_senddata) begin
		    next_state = `DTDATAFIS;
		end

	    `DTCHKTYP:	// Start the Receive Engine for receiving FIS
		if (r2t_waittxid) begin
		    /*
		     * RX FSM is done receiving
		     */ 
		    next_state = `DTTXIDLE;
		end
		else begin
		    /*
		     * RX FSM is still busy receiving
		     */ 
		    next_state = `DTCHKTYP;
		end

	    `DTREGFIS:	// Send out a Device-to-Host Register FIS
		if (~expire) begin
		    next_state = `DTREGFIS;
		end
		else begin
		    next_state = `DTREGSTA;
		end

	    `DTPIOSTUP:	// Send out a PIO Setup FIS
		if (~expire) begin
		    next_state = `DTPIOSTUP;
		end
		else begin
		    next_state = `DTPIOSSTA; 
		end

	    `DTDMASTUP:	// Send otu a DMA Setup FIS
		if (~expire) begin
		    next_state = `DTDMASTUP;
		end
		else begin
		    next_state = `DTDMASSTA;
		end

	    `DTDMAACT:	// Send out a DMA Activate FIS (only one Dword)
		next_state = `DTDMAASTA;

	    `DTXMITBIS:	// Send out a BIST Activate FIS
		if (~expire) begin
		    next_state = `DTXMITBIS;
		end
		else begin
		    next_state = `DTBISSTA;
		end

	    `DTDATAFIS:	// Send out a DATA FIS
		next_state = `DTDATATX;

	    `DTDATATX:	//*** Debug 5/7/2001: may be combined with DTDATAFIS?
		//*** Debug ***: may need signals other than expire?
		if (~expire) begin
		    next_state = `DTDATATX;
		end
		else begin
		    next_state = `DTDTXEND;
		end

	    `DTDTXEND:	//*** Debug 5/7/2001: may need a better state
		next_state = `DTTXIDLE;

	    `DTREGSTA:	// Check status after sending out a Register FIS
		if (~lk_txfsmidle & ~txtimeout) begin
		    next_state = `DTREGSTA;
		end
		else if (lk_txfsmidle & lk_txerror) begin
		    next_state = `DTREGFIS;	// Retry sending the FIS
		end
		else begin
		    next_state = `DTTXIDLE;
		end

	    `DTPIOSSTA:	// Check status after sending out a PIO Setup FIS
		if (~lk_txfsmidle & ~txtimeout) begin
		    next_state = `DTPIOSSTA;
		end
		else if (lk_txfsmidle & lk_txerror) begin
		    next_state = `DTPIOSTUP;	// Retry sending the FIS
		end
		else begin
		    next_state = `DTTXIDLE;
		end

	    `DTDMASSTA:	// Check status after sending the DMA Setup FIS
		if (~lk_txfsmidle & ~txtimeout) begin
		    next_state = `DTDMASSTA;
		end
		else if (lk_txfsmidle & lk_txerror) begin
		    next_state = `DTDMASTUP;	// Retry sending the FIS
		end
		else begin
		    next_state = `DTTXIDLE;
		end

	    `DTDMAASTA:	// Check status after sending the DMA Activate FIS
		if (~lk_txfsmidle & ~txtimeout) begin
		    next_state = `DTDMAASTA;
		end
		else if (lk_txfsmidle & lk_txerror) begin
		    next_state = `DTDMAACT;	// Retry sending the FIS
		end
		else begin
		    next_state = `DTTXIDLE;
		end

	    `DTBISSTA:	// Check status after sending the BIST Activate FIS
		if (~lk_txfsmidle & ~txtimeout) begin
		    next_state = `DTBISSTA;
		end
		else if (lk_txfsmidle & lk_txerror) begin
		    next_state = `DTXMITBIS;	// Retry sending the FIS
		end
		else begin
		    next_state = `DTTXIDLE;
		end

	    default: begin	// We should never be here
		next_state = `DTWAITTXID;
		$display (
		"*** Warning: Undefined HTP RX State, cur_state = %b ***",
		cur_state);
		end
	    endcase
	end // End else (tptx_reset == 0)

    end // End always

endmodule // dtrans_txfsm