Appendix C: Sample Verilog Files for Modeling a Controller
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