The Elements of Logic Design Style

Appendix A: Sample Verilog Files for Modeling a Module

Shing Kong

March 2001

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

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

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



Appendix A: Sample Verilog Files for Modeling a Module       $Revision: 1.1 $
-----------------------------------------------------------------------------

/****************************************************************************
 *
 * File Name: dtrans.v
 *
 * Comment: Device Dongle Transport Layer
 *
 * Author: Shing Kong
 * Creation Date: 5/9/2001
 *
 * $Source: /proj/gemini/cvs_root/P2002/Notes/Style/appendixA,v $
 * $Date: 2001/12/06 21:49:07 $
 * $Revision: 1.1 $
 *
 *===========================================================================
 * Copyright (c) 2001 by Shing Ip Kong.  All Rights Reserved.
 ****************************************************************************/
/*
 * $Id: appendixA,v 1.1 2001/12/06 21:49:07 kong Exp $
 */
module dtrans (
    // Transmit Engine's Outputs
    tp_acksendreg,
    tp_acksenddmaa,
    tp_acksendpios,
    tp_acksenddmas,
    tp_acksendbist,
    tp_acksenddata,
    tp_txdata,
    tp_txgoempty,
    tp_txempty,
    tp_sendndfis,
    tp_senddafis,
    tp_partial,
    tp_slumber,
    tp_spdsel,

    // Transmit Engine's Inputs
    at_data,
    at_error,
    at_seccnt,
    at_secnum,
    at_cyllow,
    at_cylhi,
    at_devhd,
    at_status,
    at_interrupt,
    at_sendreg,
    at_senddmaa,
    at_sendpios,
    at_senddmas,
    at_sendbista,
    at_senddata,
    lk_txfsmidle,
    lk_rdtxfifo,
    lk_txerror,
    txclk,
    txclk4x,

    // Receive Engine's Output
    tp_datain,
    tp_featurein,
    tp_seccntin,
    tp_secnumin,
    tp_cyllowin,
    tp_cylhiin,
    tp_devhdin,
    tp_cmdin,
    tp_devctlin,
    tp_cbit,
    tp_wrdata,
    tp_wrATAreg,
    tp_rxnearfull,
    tp_rxfull,
    tp_rxdabort,
    tp_fisgood,
    tp_fisundef,

    // Receive Engine's Input
    at_rxdabort,
    lk_rxdata,
    lk_wrrxfifo,
    lk_eofis,
    rxclk,
    rxclk4x,

    // Input for both the Transmit and Receive Engines
    at_reset);

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

    /*
     * Transmit Engine's Outputs to the Link Layer (link.v)
     */
    output [31:0]	tp_txdata;
    output		tp_txgoempty;
    output		tp_txempty;
    output		tp_sendndfis;	// Sending a non-data FIS
    output		tp_senddafis;	// Sending a data FIS
    output		tp_partial;
    output		tp_slumber;
    output		tp_spdsel;

    /*
     * Transmit Engine's Inputs from the Parallel ATA Interface (dataif.v)
     */
    input [15:0]	at_data;
    input [7:0]		at_error;
    input [7:0]		at_seccnt;
    input [7:0]		at_secnum;
    input [7:0]		at_cyllow;
    input [7:0]		at_cylhi;
    input [7:0]		at_devhd;
    input [7:0]		at_status;
    input		at_interrupt;

    input		at_sendreg;
    input		at_senddmaa;
    input		at_sendpios;
    input		at_senddmas;
    input		at_sendbista;
    input		at_senddata;

    /*
     * Transmit Engine's Inputs from the Link Layer (link.v)
     */
    input		lk_txfsmidle;	// TX FSM has returned to IDLE
    input		lk_rdtxfifo;
    input		lk_txerror;

    /*
     * Transmit Engine's Clocks
     */
    input		txclk;
    input 		txclk4x;

    /*
     * Receive Engine's Outputs to the Parallel ATA Interface (dataif.v)
     */
    // These signals will not be synchronized.  Instead we will
    // synchronize the "write strobe" at "dataif"--see below
    output [15:0]	tp_datain;
    output [7:0]	tp_featurein;
    output [7:0]	tp_seccntin;
    output [7:0]	tp_secnumin;
    output [7:0]	tp_cyllowin;
    output [7:0]	tp_cylhiin;
    output [7:0]	tp_devhdin;
    output [7:0]	tp_cmdin;
    output [2:1]	tp_devctlin;
    output 		tp_cbit;
    // These signals will be synchronized at "dataif"
    output		tp_wrdata;
    output		tp_wrATAreg;	// Write ATA registers (except Data)

    /*
     * Receive Engine's Outputs to the Link Layer (link.v)
     */
    output		tp_rxnearfull;
    output		tp_rxfull;
    output		tp_rxdabort;	// Data RX has been aborted
    output		tp_fisgood;	// Receive a valid FIS
    output		tp_fisundef;	// FIS not recognized by Transport

    /*
     * Receive Engine's Inputs from the Parallel ATA Interface (dataif.v)
     * These signals need to be synchronized w.r.t. the rxclk4x clock
     */
    input		at_rxdabort;	// ATA interface aborts data receiving

    /*
     * Receive Engine's Inputs from the Link Layer (link.v)
     */
    input [31:0]	lk_rxdata;
    input		lk_wrrxfifo;
    input		lk_eofis;	// Link layer finish writing the FIS

    /*
     * Receive Engine's Clocks
     */
    input		rxclk;
    input		rxclk4x;

     /*
      * Inputs to both the Transmit and Receive Engines
      */
    input		at_reset;

    /*
     * Interconnections within this module
     */
    // Outputs of the Transmit Engine (dtrans_tx.v)
    wire		txfsmidle;
    wire		txokrxgo;	// TX FSM gives RX FSM the OK

    // Outputs of the Recevie Engine (dtrans_rx.v)
    wire		waittxid;
    wire		rxempty;

    /*
     * Device Dongle Transport Layer Transmit Engine (dtrans_tx.v)
     */
    dtrans_tx dtrans_tx (
	// Outputs
	.tp_acksendreg (tp_acksendreg),
	.tp_acksenddmaa (tp_acksenddmaa),
	.tp_acksendpios (tp_acksendpios),
	.tp_acksenddmas (tp_acksenddmas),
	.tp_acksendbist (tp_acksendbist),
	.tp_acksenddata (tp_acksenddata),
	.tp_txdata (tp_txdata),		.tp_txgoempty (tp_txgoempty),
	.tp_txempty (tp_txempty),	.tp_sendndfis (tp_sendndfis),
	.tp_senddafis (tp_senddafis),	.tp_partial (tp_partial),
	.tp_slumber (tp_slumber),	.tp_spdsel (tp_spdsel),
	.txfsmidle (txfsmidle),		.txokrxgo (txokrxgo),

	// Inputs
	.at_data (at_data),		.at_error (at_error),
	.at_seccnt (at_seccnt),		.at_secnum (at_secnum),
	.at_cyllow (at_cyllow),		.at_cylhi (at_cylhi),
	.at_devhd (at_devhd),		.at_status (at_status),
	.at_interrupt (at_interrupt),	.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_rdtxfifo (lk_rdtxfifo),
	.lk_txerror (lk_txerror),	.waittxid (waittxid),
	.rxempty (rxempty),		.txclk (txclk),
	.txclk4x (txclk4x),		.at_reset (at_reset));

    /*
     * Device Dongle Transport Layer Receive Engine (dtrans_rx.v)
     */
    dtrans_rx dtrans_rx (
	// Outputs
	.tp_datain (tp_datain),		.tp_featurein (tp_featurein),
	.tp_seccntin (tp_seccntin),	.tp_secnumin (tp_secnumin),
	.tp_cyllowin (tp_cyllowin),	.tp_cylhiin (tp_cylhiin),
	.tp_devhdin (tp_devhdin),	.tp_cmdin (tp_cmdin),
	.tp_devctlin (tp_devctlin),	.tp_cbit (tp_cbit),
	.tp_wrdata (tp_wrdata),		.tp_wrATAreg (tp_wrATAreg),
	.tp_rxnearfull (tp_rxnearfull),	.tp_rxfull (tp_rxfull),
	.tp_rxdabort (tp_rxdabort),	.tp_fisgood (tp_fisgood),
	.tp_fisundef (tp_fisundef),
	.waittxid (waittxid),		.rxempty (rxempty),

	// Inputs
	.at_rxdabort (at_rxdabort),	.lk_rxdata (lk_rxdata),
	.lk_wrrxfifo (lk_wrrxfifo),	.lk_eofis (lk_eofis),
	.txfsmidle (txfsmidle),		.txokrxgo (txokrxgo),
	.rxclk (rxclk),			.rxclk4x (rxclk4x),
	.at_reset (at_reset));

endmodule // dtrans

/****************************************************************************
 *
 * File Name: dtrans_tx.v
 *
 * Comment: Device Dongle Transport Layer Transmission Engine
 *
 * Author: Shing Kong
 * Creation Date: 3/25/2001
 *
 * $Source: /proj/gemini/cvs_root/P2002/Notes/Style/appendixA,v $
 * $Date: 2001/12/06 21:49:07 $
 * $Revision: 1.1 $
 *
 *===========================================================================
 * Copyright (c) 2001 by Shing Ip Kong.  All Rights Reserved.
 ****************************************************************************/
/*
 * $Id: appendixA,v 1.1 2001/12/06 21:49:07 kong Exp $
 */
`include "trans_defs.v"		// See ../../CommonFiles

module dtrans_tx (
    // Outputs
    tp_acksendreg,
    tp_acksenddmaa,
    tp_acksendpios,
    tp_acksenddmas,
    tp_acksendbist,
    tp_acksenddata,
    tp_txdata,
    tp_txgoempty,
    tp_txempty,
    tp_sendndfis,
    tp_senddafis,
    tp_partial,
    tp_slumber,
    tp_spdsel,
    txfsmidle,
    txokrxgo,

    // Inputs
    at_data,
    at_error,
    at_seccnt,
    at_secnum,
    at_cyllow,
    at_cylhi,
    at_devhd,
    at_status,
    at_interrupt,
    at_sendreg,
    at_senddmaa,
    at_sendpios,
    at_senddmas,
    at_sendbista,
    at_senddata,
    lk_txfsmidle,
    lk_rdtxfifo,
    lk_txerror,
    waittxid,
    rxempty,
    txclk,
    txclk4x,
    at_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 [31:0]	tp_txdata;
    output		tp_txgoempty;
    output		tp_txempty;
    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

    /*
     * Inputs from the Parallel ATA Interface (dataif.v)
     */
    input [15:0]	at_data;
    input [7:0]		at_error;
    input [7:0]		at_seccnt;
    input [7:0]		at_secnum;
    input [7:0]		at_cyllow;
    input [7:0]		at_cylhi;
    input [7:0]		at_devhd;
    input [7:0]		at_status;
    input		at_interrupt;

    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_rdtxfifo;
    input		lk_txerror;

    /*
     * Inputs from the Transport Layer Receive Engine (dtrans_rx.v)
     */
    input		waittxid;
    input		rxempty;

    /*
     * Reset signal and clocks
     */
    input		txclk;
    input 		txclk4x;
    input		at_reset;

    /*
     * Interconnections within this module
     */
    // Outputs of the Synchronizer
    wire		tptx_reset;
    wire		r2t_waittxid;
    wire		r2t_rxempty;

    // Outputs of the Transport Layer Transmit Controller (dtrans_txctl.v)
    wire [`log_maxfis-1:0]
			wcount;
    wire		wrtxfifo;
    wire		sendreg;
    wire		senddmaa;
    wire		sendpios;
    wire		senddmas;
    wire		sendbista;
    wire		senddata;

    // Outputs of the Transport Layer Transmit Datapath (dtrans_txdp.v)
    wire		txfull;
    wire		txtimeout;

    /*
     * Synchronizer that synchronizes the signals to the txclk4x domain
     */
    dtrans_txsyn dtrans_txsyn (
	.tptx_reset (tptx_reset),	.r2t_waittxid (r2t_waittxid),
	.r2t_rxempty (r2t_rxempty),
	.waittxid (waittxid),		.rxempty (rxempty),
	.txclk (txclk),			.txclk4x (txclk4x),
	.at_reset (at_reset));

    /*
     * Device Transport Layer Transmit Controller (dtrans_txctl.v)
     */
    dtrans_txctl dtrans_txctl (
	// Outputs
	.tp_acksendreg (tp_acksendreg),
	.tp_acksenddmaa (tp_acksenddmaa),
	.tp_acksendpios (tp_acksendpios),
	.tp_acksenddmas (tp_acksenddmas),
	.tp_acksendbist (tp_acksendbist),
	.tp_acksenddata (tp_acksenddata),
	.tp_sendndfis (tp_sendndfis),	.tp_senddafis (tp_senddafis),
	.tp_partial (tp_partial),	.tp_slumber (tp_slumber),
	.tp_spdsel (tp_spdsel),
	.txfsmidle (txfsmidle),		.txokrxgo (txokrxgo),
	.wcount (wcount),		.wrtxfifo (wrtxfifo),
	.sendreg (sendreg),		.senddmaa (senddmaa),
	.sendpios (sendpios),		.senddmas (senddmas),
	.sendbista (sendbista),		.senddata (senddata),

	// Inputs
	.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),
	.txfull (txfull),		.txtimeout (txtimeout),
	.txclk4x (txclk4x),		.tptx_reset (tptx_reset));

    /*
     * Device Transport Layer Transmit Datapath (dtrans_txdp.v)
     */
    dtrans_txdp dtrans_txdp (
	// Outputs
	.tp_txdata (tp_txdata),		.tp_txgoempty (tp_txgoempty),
	.tp_txempty (tp_txempty),	.txfull (txfull),
	.txtimeout (txtimeout),

	// Inputs
	.at_data (at_data),		.at_error (at_error),
	.at_seccnt (at_seccnt),		.at_secnum (at_secnum),
	.at_cyllow (at_cyllow),		.at_cylhi (at_cylhi),
	.at_devhd (at_devhd),		.at_status (at_status),
	.at_interrupt (at_interrupt),	.lk_rdtxfifo (lk_rdtxfifo),
	.wcount (wcount),		.wrtxfifo (wrtxfifo),
	.sendreg (sendreg),		.senddmaa (senddmaa),
	.sendpios (sendpios),		.senddmas (senddmas),
	.sendbista (sendbista),		.senddata (senddata),
	.txclk4x (txclk4x),		.tptx_reset (tptx_reset));

endmodule // dtrans_tx

/****************************************************************************
 * Module dtrans_txsyn: Synchronize signals for the txclk4x clock domain
 ****************************************************************************/
module dtrans_txsyn (
    // Outputs
    tptx_reset,
    r2t_waittxid,
    r2t_rxempty,

    // Inputs
    waittxid,
    rxempty,
    txclk,
    txclk4x,
    at_reset);

    output	tptx_reset;

    output	r2t_waittxid;	// RX FSM waiting TX FSM to be idle
    output	r2t_rxempty;	// RX FIFO is empty

    input	waittxid;
    input	rxempty;

    input	txclk;
    input	txclk4x;

    input	at_reset;

    /*
     * Connection within this module
     */
    wire	txclk_waittxid;
    wire	txclk_rxempty;

    /*
     * Register the reset signal before using it locally
     */
    v_reg #(1) reset_ff (tptx_reset, txclk4x, at_reset);

    /*
     * For signals coming from the rxclk or rxclk4x domain,
     * Step 1: Sample it with the txclk clock.
     * Step 2: Sample it again with the txclk4x clock.
     *
     * Note: we assume the rising edges of txclk and txclk4x are aligned.
     * Consequently, sampling a signal with txclk followed by sampling it
     * with txclk4x has the same effect as sampling a signal twice with
     * txclk as far as the prevention of meta-stability is concerned.
     */
    v_reg #(1) txclk_ff0 (txclk_waittxid, txclk, waittxid);
    v_reg #(1) txclk_ff1 (txclk_rxempty, txclk, rxempty);

    v_reg #(1) syn_ff0 (r2t_waittxid, txclk4x, txclk_waittxid);
    v_reg #(1) syn_ff1 (r2t_rxempty, txclk4x, txclk_rxempty);

endmodule // dtrans_txsyn

/****************************************************************************
 *
 * File Name: dtrans_rx.v
 *
 * Comment: Device Dongle Transport Layer Receive Engine
 *
 * Author: Shing Kong
 * Creation Date: 5/3/2001
 *
 * $Source: /proj/gemini/cvs_root/P2002/Notes/Style/appendixA,v $
 * $Date: 2001/12/06 21:49:07 $
 * $Revision: 1.1 $
 *
 *===========================================================================
 * Copyright (c) 2001 by Shing Ip Kong.  All Rights Reserved.
 ****************************************************************************/
/*
 * $Id: appendixA,v 1.1 2001/12/06 21:49:07 kong Exp $
 */
module dtrans_rx (
    // Outputs
    tp_datain,
    tp_featurein,
    tp_seccntin,
    tp_secnumin,
    tp_cyllowin,
    tp_cylhiin,
    tp_devhdin,
    tp_cmdin,
    tp_devctlin,
    tp_cbit,
    tp_wrdata,
    tp_wrATAreg,
    tp_rxnearfull,
    tp_rxfull,
    tp_rxdabort,
    tp_fisgood,
    tp_fisundef,
    waittxid,
    rxempty,

    // Inputs
    at_rxdabort,
    lk_rxdata,
    lk_wrrxfifo,
    lk_eofis,
    txfsmidle,
    txokrxgo,
    rxclk,
    rxclk4x,
    at_reset);

    /*
     * Outputs to the Parallel ATA Interface Layer (dataif.v)
     */
    // These signals will not be synchronized.  Instead we will
    // synchronize the "write strobe" at "dataif"--see below
    output [15:0]	tp_datain;
    output [7:0]	tp_featurein;
    output [7:0]	tp_seccntin;
    output [7:0]	tp_secnumin;
    output [7:0]	tp_cyllowin;
    output [7:0]	tp_cylhiin;
    output [7:0]	tp_devhdin;
    output [7:0]	tp_cmdin;
    output [2:1]	tp_devctlin;
    output 		tp_cbit;

    // These signals will be synchronized at "dataif"
    output		tp_wrdata;
    output		tp_wrATAreg;	// Write ATA registers (except Data)

    /*
     * Outputs to the Link Layer (link.v)
     */
    output		tp_rxnearfull;
    output		tp_rxfull;

    output		tp_rxdabort;	// Data RX has been aborted
    output		tp_fisgood;	// Receive a valid FIS
    output		tp_fisundef;	// FIS not recognized by Transport

    /*
     * Output to the Transport Layer Transmit Engine (dtrans_tx.v)
     */
    output		waittxid;	// RX FSM waiting TX FSM to be idle
    output		rxempty;

    /*
     * Inputs from the Parallel ATA Interface Layer (dataif.v)
     * These signals need to be synchronized w.r.t. the rxclk4x clock
     */
    input		at_rxdabort;	// ATA interface aborts data receiving

    /*
     * Inputs from the Link Layer (link.v)
     */
    input [31:0]	lk_rxdata;
    input		lk_wrrxfifo;
    input		lk_eofis;	// Link layer finish writing the FIS

    /*
     * Inputs from the Transport Layer Transmit Engine (dtrans_tx.v)
     */
    input		txfsmidle;
    input		txokrxgo;		// TX FSM gives RX FSM the OK

    /*
     * Miscellaneous Inputs
     */
    input		rxclk;
    input		rxclk4x;
    input		at_reset;

    /*
     * Connections within this module
     */
    // Outputs of the Synchronizer
    wire		tprx_reset;
    wire		t2r_rxdabort;		// Abort receiving data
    wire		t2r_txfsmidle;
    wire		t2r_txokrxgo;		// TX FSM gives RX FSM the OK

    // Outputs of the Transport Layer Receive Controller (dtrans_rxctl.v)
    wire		incomefis;	// Receiving FIS
    wire		rdrxfifo;
    wire		hld_feature;
    wire		hld_seccnt;
    wire		hld_secnum;
    wire		hld_cyllow;
    wire		hld_cylhi;
    wire		hld_devhd;
    wire		hld_cmd;
    wire		hld_devctl;
    wire		hld_cbit;
    wire		upperdata;	// Use bits[31:16] of the Data FIS

    // Outputs of the Transport Layer Receive Datapath (dtrans_rxdp.v)
    wire		rxtimeout;
    wire		hregfis;
    wire		dmasfis;
    wire		bisafis;
    wire		datafis;

    /*
     * Synchronizer that synchronize the signals to the rxclk4x domain
     */
    dtrans_rxsyn dtrans_rxsyn (
	// Outputs
	.tprx_reset (tprx_reset),	.t2r_rxdabort (t2r_rxdabort),
	.t2r_txfsmidle (t2r_txfsmidle),	.t2r_txokrxgo (t2r_txokrxgo),

	// Inputs
	.at_reset (at_reset),	.at_rxdabort (at_rxdabort),
	.txfsmidle (txfsmidle),		.txokrxgo (txokrxgo),
	.rxclk (rxclk),			.rxclk4x (rxclk4x));

    /*
     * Device Transport Layer Receive Controller (dtrans_rxctl.v)
     */
    dtrans_rxctl dtrans_rxctl (
	// Outputs
	.tp_wrdata (tp_wrdata),		.tp_wrATAreg (tp_wrATAreg),
	.tp_rxdabort (tp_rxdabort),	.tp_fisgood (tp_fisgood),
	.tp_fisundef (tp_fisundef),	.waittxid (waittxid),
	.incomefis (incomefis),		.rdrxfifo (rdrxfifo),
	.hld_feature (hld_feature),	.hld_seccnt (hld_seccnt),
	.hld_secnum (hld_secnum),	.hld_cyllow (hld_cyllow),
	.hld_cylhi (hld_cylhi),		.hld_devhd (hld_devhd),
	.hld_cmd (hld_cmd),		.hld_devctl (hld_devctl),
	.hld_cbit (hld_cbit),		.upperdata (upperdata),

	// Inputs
	.t2r_rxdabort (t2r_rxdabort),	.lk_eofis (lk_eofis),
	.t2r_txfsmidle (t2r_txfsmidle), .t2r_txokrxgo (t2r_txokrxgo),
	.rxempty (rxempty),		.rxtimeout (rxtimeout),
	.hregfis (hregfis),		.dmasfis (dmasfis),
	.bisafis (bisafis),		.datafis (datafis),
	.rxclk4x (rxclk4x),		.tprx_reset (tprx_reset));

    /*
     * Device Transport Layer Receive Datapath (dtrans_rxdp.v)
     */
    dtrans_rxdp dtrans_rxdp (
	// Outputs
	.tp_datain (tp_datain),		.tp_featurein (tp_featurein),
	.tp_seccntin (tp_seccntin),	.tp_secnumin (tp_secnumin),
	.tp_cyllowin (tp_cyllowin),	.tp_cylhiin (tp_cylhiin),
	.tp_devhdin (tp_devhdin),	.tp_cmdin (tp_cmdin),
	.tp_devctlin (tp_devctlin),	.tp_cbit (tp_cbit),
	.tp_rxnearfull (tp_rxnearfull),	.tp_rxfull (tp_rxfull),
	.rxempty (rxempty),		.rxtimeout (rxtimeout),
	.hregfis (hregfis),		.dmasfis (dmasfis),
	.bisafis (bisafis),		.datafis (datafis),

	// Inputs
	.lk_rxdata (lk_rxdata),		.lk_wrrxfifo (lk_wrrxfifo),
	.incomefis (incomefis),		.rdrxfifo (rdrxfifo),
	.hld_feature (hld_feature),	.hld_seccnt (hld_seccnt),
	.hld_secnum (hld_secnum),	.hld_cyllow (hld_cyllow),
	.hld_cylhi (hld_cylhi),		.hld_devhd (hld_devhd),
	.hld_cmd (hld_cmd),		.hld_devctl (hld_devctl),
	.hld_cbit (hld_cbit),		.upperdata (upperdata),
	.rxclk4x (rxclk4x),		.tprx_reset (tprx_reset));

endmodule // dtrans_rx

/****************************************************************************
 * Module dtrans_rxsyn: Synchronize signals for the rxclk4x clock domain
 ****************************************************************************/
module dtrans_rxsyn (
    // Outputs
    tprx_reset,
    t2r_rxdabort,
    t2r_txfsmidle,
    t2r_txokrxgo,

    // Inputs
    at_rxdabort,
    txfsmidle,
    txokrxgo,
    rxclk,
    rxclk4x,
    at_reset);

    output	tprx_reset;

    output	t2r_rxdabort;		// Abort receiving data
    output	t2r_txfsmidle;
    output	t2r_txokrxgo;		// TX FSM gives RX FSM the OK

    input	at_rxdabort;	// ATA interface aborts data receiving
    input	txfsmidle;
    input	txokrxgo;	// TX FSM gives RX FSM the OK

    input	rxclk;
    input	rxclk4x;
    input	at_reset;

    /*
     * Interconnections within this module
     */
    wire	rxclk_rxdabort;		// Abort receiving data
    wire	rxclk_txfsmidle;
    wire	rxclk_txokrxgo;		// TX FSM gives RX FSM the OK

    v_reg #(1) reset_ff (tprx_reset, rxclk4x, at_reset);

    /*
     * For signals coming from the txclk or txclk4x domain,
     * Step 1: Sample it with the rxclk clock.
     * Step 2: Sample it again with the rxclk4x clock.
     *
     * Note: we assume the rising edges of rxclk and rxclk4x are aligned.
     * Consequently, sampling a signal with rxclk followed by sampling it
     * with rxclk4x has the same effect as sampling a signal twice with
     * rxclk as far as the prevention of meta-stability is concerned.
     */
    v_reg #(1) rxclk_ff0 (rxclk_rxdabort, rxclk, at_rxdabort);
    v_reg #(1) rxclk_ff1 (rxclk_txfsmidle, rxclk, txfsmidle);
    v_reg #(1) rxclk_ff2 (rxclk_txokrxgo, rxclk, txokrxgo);

    v_reg #(1) syn_ff0 (t2r_rxdabort, rxclk4x, rxclk_rxdabort);
    v_reg #(1) syn_ff1 (t2r_txfsmidle, rxclk4x, rxclk_txfsmidle);
    v_reg #(1) syn_ff2 (t2r_txokrxgo, rxclk4x, rxclk_txokrxgo);

endmodule // dtrans_rxsyn