from magma import *

UARTTX = DefineCircuit("UARTTX",
                     "data_in", In(Bits(8)),
                     "send_character", In(Bit),
                     "en_16_x_baud", In(Bit),
                     "serial_out", Out(Bit),
                     "Tx_complete", Out(Bit),
                     "CLK", In(Clock))
UARTTX.verilog = '''
//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

        // O = (bit_select ? data_in[1] : data_in[0]) | !tx_run
  	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) );

        // O = bit_select & tx_run
	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

        // ready = stop & send
  	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

        // start = ready
  	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
       // run = start | (run & !carry)
  	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

      // hot = ready | bit
  	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
       // stop = (run & carry) | (stop & !send)
  	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

  // complete = carry & baud
  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
'''
