////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2004 Xilinx, Inc.
// All Rights Reserved
////////////////////////////////////////////////////////////////////////////////
//   ____  ____
//  /   /\/   /
// /___/  \  /    Vendor: Xilinx
// \   \   \/     Version: 1.03
//  \   \         Filename: kcuart_tx.v
//  /   /         Date Last Modified:  November 2, 2004
// /___/   /\     Date Created: October 14, 2002
// \   \  /  \
//  \___\/\___\
//
//Device:  	Xilinx
//Purpose: 	
// 	Constant (K) Compact UART Transmitter
//Reference:
// 	None
//Revision History:
//    Rev 1.00 - kc - Start of design entry in VHDL,  October 14, 2002
//    Rev 1.01 - sus - Converted to verilog,  August 4, 2004
//    Rev 1.02 - njs - Synplicity attributes added,  September 6, 2004
//    Rev 1.03 - njs - Fixed simulation attributes from string to hex, 
//				November 2, 2004
////////////////////////////////////////////////////////////////////////////////// 
// Contact: e-mail  picoblaze@xilinx.com
//////////////////////////////////////////////////////////////////////////////////
//
// Disclaimer: 
// LIMITED WARRANTY AND DISCLAIMER. These designs are
// provided to you "as is". Xilinx and its licensors make and you
// receive no warranties or conditions, express, implied,
// statutory or otherwise, and Xilinx specifically disclaims any
// implied warranties of merchantability, non-infringement, or
// fitness for a particular purpose. Xilinx does not warrant that
// the functions contained in these designs will meet your
// requirements, or that the operation of these designs will be
// uninterrupted or error free, or that defects in the Designs
// will be corrected. Furthermore, Xilinx does not warrant or
// make any representations regarding use or the results of the
// use of the designs in terms of correctness, accuracy,
// reliability, or otherwise.
//
// LIMITATION OF LIABILITY. In no event will Xilinx or its
// licensors be liable for any loss of data, lost profits, cost
// or procurement of substitute goods or services, or for any
// special, incidental, consequential, or indirect damages
// arising from the use or operation of the designs or
// accompanying documentation, however caused and on any theory
// of liability. This limitation will apply even if Xilinx
// has been advised of the possibility of such damage. This
// limitation shall apply not-withstanding the failure of the 
// essential purpose of any limited remedies herein. 
//////////////////////////////////////////////////////////////////////////////////

`timescale 1 ps / 1ps

module kcuart_tx
     (data_in,
      send_character,
      en_16_x_baud,
      serial_out,
      Tx_complete,
      clk);

input 	[7:0]	data_in;
input       	send_character;
input       	en_16_x_baud;
output		serial_out;
output		Tx_complete;
input 		clk;

//
////////////////////////////////////////////////////////////////////////////////////
//
// Start of KCUART_TX
//	 
//
////////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////////
//
// wires used in KCUART_TX
//
////////////////////////////////////////////////////////////////////////////////////
//
wire 		data_01;
wire 		data_23;
wire 		data_45;
wire 		data_67;
wire 		data_0123;
wire 		data_4567;
wire 		data_01234567;
wire 	[2:0] 	bit_select;
wire 	[2:0] 	next_count;
wire 	[2:0] 	mask_count;
wire 	[2:0] 	mask_count_carry;
wire 	[2:0] 	count_carry;
wire 		ready_to_start;
wire 		decode_Tx_start;
wire 		Tx_start;
wire 		decode_Tx_run;
wire 		Tx_run;
wire 		decode_hot_state;
wire 		hot_state;
wire 		hot_delay;
wire 		Tx_bit;
wire 		decode_Tx_stop;
wire 		Tx_stop;
wire 		decode_Tx_complete;
//
//
////////////////////////////////////////////////////////////////////////////////////
//
// Attributes to define LUT contents during implementation 
// The information is repeated in the generic map for functional simulation//
//
////////////////////////////////////////////////////////////////////////////////////

// synthesis attribute init of mux1_lut is "E4FF"; 
// synthesis attribute init of mux2_lut is "E4FF";
// synthesis attribute init of mux3_lut is "E4FF";
// synthesis attribute init of mux4_lut is "E4FF";
// synthesis attribute init of ready_lut is "10";
// synthesis attribute init of start_lut is "0190";
// synthesis attribute init of run_lut is "1540";
// synthesis attribute init of hot_state_lut is "94";
// synthesis attribute init of delay14_srl is "0000";
// synthesis attribute init of stop_lut is "0180";
// synthesis attribute init of complete_lut is "8";
// synthesis attribute init of count_lut_0 is "8";
// synthesis attribute init of count_lut_1 is "8";
// synthesis attribute init of count_lut_2 is "8";

//
////////////////////////////////////////////////////////////////////////////////////
//
// Start of KCUART_TX circuit description
//
////////////////////////////////////////////////////////////////////////////////////
//	

  // 8 to 1 multiplexer to convert parallel data to serial

  	LUT4 mux1_lut
  	  ( .I0(bit_select[0]),
   	    .I1(data_in[0]),
            .I2(data_in[1]),
            .I3(Tx_run),
            .O(data_01) )/* synthesis xc_props = "INIT=E4FF"*/;
	// synthesis translate_off
	defparam mux1_lut.INIT = 16'hE4FF; 
	// synthesis translate_on

  	LUT4 mux2_lut 
  	(   .I0(bit_select[0]),
            .I1(data_in[2]),
            .I2(data_in[3]),
            .I3(Tx_run),
            .O(data_23) )/* synthesis xc_props = "INIT=E4FF"*/;
	// synthesis translate_off
	defparam mux2_lut.INIT = 16'hE4FF; 
	// synthesis translate_on

  	LUT4 mux3_lut
  	   (.I0(bit_select[0]),
            .I1(data_in[4]),
            .I2(data_in[5]),
            .I3(Tx_run),
            .O(data_45) )/* synthesis xc_props = "INIT=E4FF"*/;
	// synthesis translate_off
	defparam mux3_lut.INIT = 16'hE4FF; 
	// synthesis translate_on

  	LUT4 mux4_lut
  	   (.I0(bit_select[0]),
            .I1(data_in[6]),
            .I2(data_in[7]),
            .I3(Tx_run),
            .O(data_67) )/* synthesis xc_props = "INIT=E4FF"*/;
	// synthesis translate_off
	defparam mux4_lut.INIT = 16'hE4FF; 
	// synthesis translate_on

  	MUXF5 mux5_muxf5
  		(		.I1(data_23),
            .I0(data_01),
            .S(bit_select[1]),
            .O(data_0123) );

  	MUXF5 mux6_muxf5
  		( 		.I1(data_67),
            .I0(data_45),
            .S(bit_select[1]),
            .O(data_4567) );

  	MUXF6 mux7_muxf6
  		(		.I1(data_4567),
            .I0(data_0123),
            .S(bit_select[2]),
            .O(data_01234567) );

  // Register serial output and force start and stop bits

  	FDRS pipeline_serial
   	(   .D(data_01234567),
            .Q(serial_out),
            .R(Tx_start),
            .S(Tx_stop),
            .C(clk) ) ;

  // 3-bit counter
  // Counter is clock enabled by en_16_x_baud
  // Counter will be reset when 'Tx_start' is active
  // Counter will increment when Tx_bit is active
  // Tx_run must be active to count
  // count_carry[2] indicates when terminal count [7] is reached and Tx_bit=1 (ie overflow)

	FDRE register_bit_0
   	(.D(next_count[0]),
         .Q(bit_select[0]),
         .CE(en_16_x_baud),
         .R(Tx_start),
         .C(clk) );

	LUT2 count_lut_0
     	(.I0(bit_select[0]),
         .I1(Tx_run),
         .O(mask_count[0]) )/* synthesis xc_props = "INIT=8"*/;
	// synthesis translate_off
	defparam count_lut_0.INIT = 4'h8; 					 
	// synthesis translate_on

   MULT_AND mask_and_0
   	(.I0(bit_select[0]),
       	 .I1(Tx_run),
         .LO(mask_count_carry[0]) );

	MUXCY count_muxcy_0
   	( .DI(mask_count_carry[0]),
         .CI(Tx_bit),
         .S(mask_count[0]),
         .O(count_carry[0]) );
       
	XORCY count_xor_0
   	(.LI(mask_count[0]),
         .CI(Tx_bit),
         .O(next_count[0]) );
 
	FDRE register_bit_1
     	(.D(next_count[1]),
         .Q(bit_select[1]),
         .CE(en_16_x_baud),
         .R(Tx_start),
         .C(clk) );

	LUT2 count_lut_1
     	(.I0(bit_select[1]),
         .I1(Tx_run),
         .O(mask_count[1]) )/* synthesis xc_props = "INIT=8"*/;
	// synthesis translate_off
	defparam count_lut_1.INIT = 4'h8; 					 
	// synthesis translate_on

   MULT_AND mask_and_1
     	( 	.I0(bit_select[1]),
         .I1(Tx_run),
         .LO(mask_count_carry[1]) );

	MUXCY count_muxcy_1
   	( 	.DI(mask_count_carry[1]),
         .CI(count_carry[0]),
         .S(mask_count[1]),
         .O(count_carry[1]) );
       
	XORCY count_xor_1
     	( 	.LI(mask_count[1]),
         .CI(count_carry[0]),
         .O(next_count[1]) );

	FDRE register_bit_2
     	( 	.D(next_count[2]),
         .Q(bit_select[2]),
         .CE(en_16_x_baud),
         .R(Tx_start),
         .C(clk) );

  	LUT2 count_lut_2
   	( 	.I0(bit_select[2]),
         .I1(Tx_run),
         .O(mask_count[2]) )/* synthesis xc_props = "INIT=8"*/;
	// synthesis translate_off
	defparam count_lut_2.INIT = 4'h8; 					 
	// synthesis translate_on
	
	MULT_AND mask_and_2
     	( 	.I0(bit_select[2]),
         .I1(Tx_run),
         .LO(mask_count_carry[2]) );


	MUXCY count_muxcy_2
   	( 	.DI(mask_count_carry[2]),
         .CI(count_carry[1]),
         .S(mask_count[2]) ,
         .O(count_carry[2]) );
       
	XORCY count_xor_2
		( 	.LI(mask_count[2]),
         .CI(count_carry[1]),
         .O(next_count[2]) );

  // Ready to start decode

  	LUT3 ready_lut
  		( 	.I0(Tx_run),
         .I1(Tx_start),
         .I2(send_character),
         .O(ready_to_start ) )/* synthesis xc_props = "INIT=10"*/;
	// synthesis translate_off
	defparam ready_lut.INIT = 8'h10; 
	// synthesis translate_on

  // Start bit enable

  	LUT4 start_lut
  		( 	.I0(Tx_bit),
         .I1(Tx_stop),
         .I2(ready_to_start),
         .I3(Tx_start),
         .O(decode_Tx_start ) )/* synthesis xc_props = "INIT=0190"*/;
	// synthesis translate_off
	defparam start_lut.INIT = 16'h0190; 
	// synthesis translate_on

  	FDE Tx_start_reg
  	(	.D(decode_Tx_start),
      .Q(Tx_start),
      .CE(en_16_x_baud),
      .C(clk) );


  // Run bit enable
  	LUT4 run_lut
  	( 	.I0(count_carry[2]),
      .I1(Tx_bit),
      .I2(Tx_start),
      .I3(Tx_run),
		.O(decode_Tx_run ) )/* synthesis xc_props = "INIT=1540"*/;
	// synthesis translate_off
	defparam run_lut.INIT = 16'h1540; 
	// synthesis translate_on

  	FDE Tx_run_reg
  	(	.D(decode_Tx_run),
      .Q(Tx_run),
      .CE(en_16_x_baud),
      .C(clk) );

  // Bit rate enable

  	LUT3 hot_state_lut
  	(	.I0(Tx_stop),
      .I1(ready_to_start),
      .I2(Tx_bit),
      .O(decode_hot_state) )/* synthesis xc_props = "INIT=94"*/;
	// synthesis translate_off
	defparam hot_state_lut.INIT = 8'h94; 
	// synthesis translate_on

  	FDE hot_state_reg
  	(	.D(decode_hot_state),
      .Q(hot_state),
      .CE(en_16_x_baud),
      .C(clk) );

  	SRL16E delay14_srl
  	(	.D(hot_state),
      .CE(en_16_x_baud),
      .CLK(clk),
      .A0(1'b1),
      .A1(1'b0),
      .A2(1'b1),
      .A3(1'b1),
      .Q(hot_delay) )/* synthesis xc_props = "INIT=0000"*/;
	// synthesis translate_off
	defparam delay14_srl.INIT = 16'h0000; 
	// synthesis translate_on

  	FDE Tx_bit_reg
  	(	.D(hot_delay),
     	.Q(Tx_bit),
      .CE(en_16_x_baud),
      .C(clk) );

  // Stop bit enable
  	LUT4 stop_lut
  	(	.I0(Tx_bit),
      .I1(Tx_run),
      .I2(count_carry[2]),
      .I3(Tx_stop),	  
      .O(decode_Tx_stop) )/* synthesis xc_props = "INIT=0180"*/;
	// synthesis translate_off
	defparam stop_lut.INIT = 16'h0180; 
	// synthesis translate_on

  FDE Tx_stop_reg
  ( 	    .D(decode_Tx_stop),
            .Q(Tx_stop),
            .CE(en_16_x_baud),
            .C(clk) );

  // Tx_complete strobe

  LUT2 complete_lut
  ( 	    .I0(count_carry[2]),
            .I1(en_16_x_baud),
            .O(decode_Tx_complete) )/* synthesis xc_props = "INIT=8"*/;
	// synthesis translate_off
	defparam complete_lut.INIT = 4'h8; 
	// synthesis translate_on

  FD Tx_complete_reg
  ( 	     .D(decode_Tx_complete),
             .Q(Tx_complete),
             .C(clk) );


endmodule

////////////////////////////////////////////////////////////////////////////////////
//
// END OF FILE KCUART_TX.V
//
////////////////////////////////////////////////////////////////////////////////////


