OpenCores
URL https://opencores.org/ocsvn/m16c5x/m16c5x/trunk

Subversion Repositories m16c5x

[/] [m16c5x/] [trunk/] [RTL/] [Src/] [UART_TXSM.v] - Rev 2

Compare with Previous | Blame | View Log

////////////////////////////////////////////////////////////////////////////////
//
//  Copyright 2008-2013 by Michael A. Morris, dba M. A. Morris & Associates
//
//  All rights reserved. The source code contained herein is publicly released
//  under the terms and conditions of the GNU Lesser Public License. No part of
//  this source code may be reproduced or transmitted in any form or by any
//  means, electronic or mechanical, including photocopying, recording, or any
//  information storage and retrieval system in violation of the license under
//  which the source code is released.
//
//  The source code contained herein is free; it may be redistributed and/or
//  modified in accordance with the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either version 2.1 of
//  the GNU Lesser General Public License, or any later version.
//
//  The source code contained herein is freely released WITHOUT ANY WARRANTY;
//  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
//  PARTICULAR PURPOSE. (Refer to the GNU Lesser General Public License for
//  more details.)
//
//  A copy of the GNU Lesser General Public License should have been received
//  along with the source code contained herein; if not, a copy can be obtained
//  by writing to:
//
//  Free Software Foundation, Inc.
//  51 Franklin Street, Fifth Floor
//  Boston, MA  02110-1301 USA
//
//  Further, no use of this source code is permitted in any form or means
//  without inclusion of this banner prominently in any derived works.
//
//  Michael A. Morris
//  Huntsville, AL
//
////////////////////////////////////////////////////////////////////////////////
 
`timescale 1ns / 1ps
 
///////////////////////////////////////////////////////////////////////////////
// Company:         M. A. Morris & Associates
// Engineer:        Michael A. Morris
//
// Create Date:     21:22:38 05/10/2008 
// Design Name:     Synchronous Serial Peripheral (SSP) Interface UART 
// Module Name:     ../VerilogCoponentsLib/SSP_UART/UART_TXSM.v
// Project Name:    Verilog Components Library
// Target Devices:  XC3S50A-4VQG100I, XC3S20A-4VQG100I, XC3S700AN-4FFG484I 
// Tool versions:   ISE 10.1i SP3 
//
// Description: This module implements the Transmit State Machine for the SSP
//              UART.
//
//              The Baud Rate Generator implements the 16 baud rates defined
//              in Table 3 of the SSP UART Specification.
//
// Dependencies:    None 
//
// Revision History:
//
//  0.01    08E10   MAM     File Created
//
//  1.00    08E24   MAM     Modified and tested TxSM to allow for several addi-
//                          tional conditions regarding Mode 1 - RS232 w/ Hand-
//                          shaking. In particular, TxSM goes to pStart from 
//                          pShift if CTS is not asserted when the current word
//                          has been shifted.
//
//  1.10    08E28   MAM     Modified to remove I/O signals best processed above
//                          this module: RTSi, RTSo, and DE. Removed from port
//                          list and moved the decoded state ouput bits to the
//                          end of the port list. Modified the TSRI and the TSR
//                          length. TSRI now only processes the two MSBs of the
//                          TSR load value. The length of TSR modified from 12
//                          to 10 bits because the logic 1 fill value and the 
//                          bit counter allow the stop bits to be implicit. The
//                          result is a faster signal path.
//
//  1.20    08F08   MAM     Modified TxSM to use a ROM to decode the [3:0]FMT
//                          input like the RxSM. Changed the SR implementation 
//                          of the shift register into a registered multiplexer
//                          implementation. Removed the bit counter and added
//                          states to the SM to multiplex the data. Result is a
//                          SM and SR that synthesizes to a speed that matches
//                          the reported speed of the RxSM: 110+ MHz. This may
//                          indicated that this UART may be useful as a high-
//                          speed UART with an 8x over-sample instead of a 4x
//                          oversample using a 48MHz clock input and a 2x DLL.
//
//  1.21    08F12   MAM     Pulled Format Decoder ROM and moved to upper level
//                          module. Added the outputs of the ROM to the port
//                          list of the module. Module now supports more format
//                          directly with the new direct inputs including com-
//                          binations not normally used. The upper level module
//                          must restrict the format inputs to those that are 
//                          proper. 7-bit formats require parity, and if not
//                          set on input, then the parity generated will be 
//                          that specified by the Par bits.
//
//  2.00    11B06   MAM     Converted to Verilog 2001.
//
//  2.01    13G06   MAM     Corrected placement of #1 delay statements. Changed
//                          combinatorial always to use @(*) instead of explicit
//                          listing of signals in sensitivity list.
//
// Additional Comments: 
//
///////////////////////////////////////////////////////////////////////////////
 
module UART_TXSM(
    input   Rst,
    input   Clk,
 
    input   CE_16x,         // 16x Clock Enable - Baud Rate x16
 
    input   Len,            // Word length: 0 - 8-bits; 1 - 7 bits
    input   NumStop,        // Number Stop Bits: 0 - 1 Stop; 1 - 2 Stop
    input   ParEn,          // Parity Enable
    input   [1:0] Par,      // 0 - Odd; 1 - Even; 2 - Space (0); 3 - Mark (1)
 
    input   TF_EF,          // Transmit THR Empty Flag
 
    input   [7:0] THR,      // Transmit Holding Register
    output  reg TF_RE,      // Transmit THR Read Enable Strobe
 
    input   CTSi,           // RS232 Mode CTS input
 
    output  reg TxD,        // Serial Data Out, LSB First, Start bit = 0
 
    output  TxIdle,         // Transmit State Machine - Idle State
    output  TxStart,        // Transmit State Machine - Start State - CTS wait
    output  TxShift,        // Transmit State Machine - Shift State
    output  TxStop          // Transmit State Machine - Stop State - RTS clear
);
 
///////////////////////////////////////////////////////////////////////////////
//
//  Module Parameters
// 
 
localparam  pIdle       =  0;   // Idle  - wait for data
localparam  pStopDelay  =  1;   // Stop  - deassert DE/RTS after 1 bit delay
localparam  pStartDelay =  2;   // Start - assert DE/RTS, delay 1 bit & CTSi
localparam  pUnused     =  3;   // Unused State
localparam  pStartBit   = 10;   // Shift - transmit Start Bit
localparam  pShift0     = 11;   // Shift - transmit TSR contents (LSB)
localparam  pShift1     =  9;   // Shift - transmit TSR contents
localparam  pShift2     =  8;   // Shift - transmit TSR contents
localparam  pShift3     = 12;   // Shift - transmit TSR contents
localparam  pShift4     = 13;   // Shift - transmit TSR contents
localparam  pShift5     = 15;   // Shift - transmit TSR contents
localparam  pShift6     = 14;   // Shift - transmit TSR contents
localparam  pShift7     =  6;   // Shift - transmit TSR contents (MSB)
localparam  pParityBit  =  4;   // Shift - transmit Parity Bit
localparam  pStopBit2   =  5;   // Shift - transmit Stop Bit 1
localparam  pStopBit1   =  7;   // Shift - transmit Stop Bit 2
 
///////////////////////////////////////////////////////////////////////////////    
//
//  Local Signal Declarations
//
 
    reg     [3:0] Bit;      // Bit Rate Divider
    reg     CE_BCnt;        // CEO Bit Rate Divider
 
    wire    Odd, Evn;       // Odd/Even parity signals
    reg     ParBit;         // Computed/assigned Parity Bit
 
    reg     [8:0] TSR;      // Transmit Shift Register
 
    (* FSM_ENCODING="SEQUENTIAL", 
       SAFE_IMPLEMENTATION="YES", 
       SAFE_RECOVERY_STATE="4'b0" *) 
    reg [3:0] TxSM = pIdle; // Xmt State Machine
 
///////////////////////////////////////////////////////////////////////////////    
//
//  Implementation
//
 
//  Set Transmit Idle Status Bit
 
assign TxIdle  = (TxSM == pIdle);       // Idle state
assign TxStop  = (TxSM == pStopDelay);  // Wait 1 bit to release line
assign TxStart = (TxSM == pStartDelay); // Take line and settle 1 bit
assign TxShift = (TxSM[3] | TxSM[2]);   // Xmt Shift States
 
//  Transmit State Machine Clock Enable
 
assign CE_TxSM = (TxIdle ? CE_16x : CE_BCnt);
 
//  Shift Register Load Signal
 
assign Ld_TSR = CE_TxSM & ~TF_EF & CTSi
                & (  (TxSM == pStartDelay)
                   | (TxSM == pStopBit1)
                   | (TxSM == pStopDelay) );
 
//  Generate Transmit FIFO Read Enable
 
always @(posedge Clk)
begin
    if(TxIdle)
        TF_RE <= #1 1'b0;
    else
        TF_RE <= #1 Ld_TSR;
end
 
//  Determine Load Value for Transmit Shift Register
 
assign Evn = ((Len) ? ^{1'b0, THR[6:0]} : ^THR);
assign Odd = ~Evn;
 
always @(*)
begin
    case(Par)
        2'b00 : ParBit <= Odd;  // Odd
        2'b01 : ParBit <= Evn;  // Even
        2'b10 : ParBit <= 0;    // Space
        2'b11 : ParBit <= 1;    // Mark
    endcase
end
 
//  Transmit Shift Register
 
always @(posedge Clk)
begin
    if(TxIdle)
        TSR <= #1 9'b1_1111_1111;
    else if(Ld_TSR)
        TSR <= #1 {ParBit, THR[7:0]};
end
 
always @(posedge Clk)
begin
    if(Rst)
        #1 TxD <= 1;
    else case(TxSM)
        pStartBit   : #1 TxD <= 0;
        pShift0     : #1 TxD <= TSR[0];
        pShift1     : #1 TxD <= TSR[1];
        pShift2     : #1 TxD <= TSR[2];
        pShift3     : #1 TxD <= TSR[3];
        pShift4     : #1 TxD <= TSR[4];
        pShift5     : #1 TxD <= TSR[5];
        pShift6     : #1 TxD <= TSR[6];
        pShift7     : #1 TxD <= TSR[7];
        pParityBit  : #1 TxD <= TSR[8];
        default     : #1 TxD <= 1;
    endcase
end
 
//  Bit Rate Divider
 
always @(posedge Clk)
begin
    if(TxIdle)
        Bit <= #1 4'b0;
    else if(CE_16x)
        Bit <= #1 Bit + 1;
end
 
always @(posedge Clk)
begin
    if(TxIdle)
        CE_BCnt <= #1 0;
    else
        CE_BCnt <= #1 CE_16x & (Bit == 4'b1111);
end
 
//  Transmit State Machine
 
always @(posedge Clk)
begin
    if(Rst)
        #1 TxSM <= pIdle;
    else if(CE_TxSM)
        case(TxSM)
            pIdle       : TxSM <= #1 ((TF_EF) ? pIdle 
                                              : pStartDelay);
 
            pStartDelay : TxSM <= #1 ((TF_EF) ? pIdle
                                              : ((CTSi) ? pStartBit 
                                                        : pStartDelay));
 
            pStartBit   : TxSM <= #1 pShift0;
            pShift0     : TxSM <= #1 pShift1;
            pShift1     : TxSM <= #1 pShift2;
            pShift2     : TxSM <= #1 pShift3;
            pShift3     : TxSM <= #1 pShift4;
            pShift4     : TxSM <= #1 pShift5;
            pShift5     : TxSM <= #1 pShift6;
            pShift6     : TxSM <= #1 ((Len)   ? pParityBit
                                              : pShift7   );
            pShift7     : TxSM <= #1 ((ParEn) ? pParityBit
                                              : ((NumStop) ? pStopBit2
                                                           : pStopBit1));
 
            pParityBit  : TxSM <= #1 ((NumStop) ? pStopBit2
                                                : pStopBit1);
 
            pStopBit2   : TxSM <= #1 pStopBit1;
            pStopBit1   : TxSM <= #1 ((TF_EF) ? pStopDelay
                                              : pStartBit );
 
            pStopDelay  : TxSM <= #1 ((TF_EF) ? pIdle
                                              : ((CTSi) ? pStartBit
                                                        : pStartDelay));
 
            pUnused     : TxSM <= #1 pIdle;
        endcase 
end
 
endmodule
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.