///////////////////////////////////////////////////////////////////////////////////////////////////
// File: TVS_to_UART.v
//-------------------------------------------------------------------
//
//  © 2022 Microchip Technology Inc. and its subsidiaries
//  All rights reserved.
//                                                                 
//  ANY USE OR REDISTRIBUTION IN PART OR IN WHOLE MUST BE HANDLED IN
//  ACCORDANCE WITH THE MICROCHIP LICENSE AGREEMENT AND MUST BE APPROVED
//  IN ADVANCE IN WRITING.
//
//------------------------------------------------------------------
// Title       : TVS_to_UART
// Created     : November-2018
// Description : TVS to UART module gives the voltage and temperature.
//    
// Revision    : 1.0 Initial Release
//               1.1 Minor signal correction for Libero v2022.1 updates
//                                   
//Targeted device: <Family::PolarFire> <Die::MPF300T_ES> <Package::FCG1152>
//
/////////////////////////////////////////////////////////////////////////////////////////////////// 

module TVS_to_UART( 

 //clock and reset
 input  wire        clk_i,
 input  wire        resetn_i,

 //TVS IF
 input  wire        valid_i,
 input  wire [15:0] value_i,
 input  wire [1:0]  channel_i,

 //Core UART IF
 input  wire        rxrdy_i,
 input  wire        txrdy_i,

 output wire        wen_o,
 output reg         oen_o,
 output wire [7:0]  data_in_o

  );

//data from TVS
reg  [15:0] tvs_value;
reg  [1:0]  tvs_channel;
reg         tvs_valid_delay1;
reg         tvs_valid_delay2;
wire        tvs_valid_posedge;

//fifo controls
reg  [7:0]  data_to_fifo;
reg         fifo_we;
wire        fifo_re;
wire        fifo_dvld;
wire        fifo_empty;
wire        fifo_afull;

//count TVS to fifo 8-bit data 
reg  [1:0]  count;

assign tvs_valid_posedge = tvs_valid_delay1 & (~tvs_valid_delay2);
assign wen_o = ~(fifo_dvld);
//get the temperature and voltage 

always@(posedge clk_i)
begin
   if(!resetn_i)
   begin
      tvs_value        <=   0;
      tvs_channel      <=   0;
      tvs_valid_delay1 <=   0;
      tvs_valid_delay2 <=   0;
   end
   else
   begin
      tvs_valid_delay1 <=   valid_i;
      tvs_valid_delay2 <=   tvs_valid_delay1;
      if(tvs_valid_posedge)
      begin
         tvs_value     <=   value_i;
         tvs_channel   <=   channel_i;
      end
   end
end

//UART handshake and fifo control   

always@(posedge clk_i)
begin
   if(!resetn_i)
   begin
      oen_o            <=   1'b1;
      fifo_we          <=   1'b0;
      count            <=   2'b00;
   end
   else
   begin
      if(rxrdy_i == 1'b1) //UART handshake -- connect
      begin
         oen_o         <=   1'b0;
         count         <=   2'b11;
      end
      else
      begin
         oen_o         <=   1'b1;
         if(tvs_valid_posedge && (!fifo_afull)) //start counter
         begin        
            fifo_we       <=   1'b1;
            count         <=   2'b01;
         end
         else if(count != 2'b00)
         begin
            count         <=   count + 1'b1;
            fifo_we       <=   1'b1;
         end
         else         
            fifo_we       <=   1'b0;         
      end
   end
end

//send TVS values to FIFO  

always@(posedge clk_i)
begin
   if(!resetn_i)
   begin
      data_to_fifo     <=   8'b0;
   end
   else
   begin
      if(count == 2'b00)
         //data_to_fifo  <=  value_i[7:0];
         data_to_fifo  <=  tvs_value[7:0];
      else if(count == 2'b01)
         data_to_fifo  <=  tvs_value[15:8];
      else if(count == 2'b10)
         data_to_fifo  <=  {6'b0,tvs_channel[1:0]};
      else
         data_to_fifo  <=  8'h61;//For UART ACK - 'a'
   end
end

//send data to UART
assign fifo_re = txrdy_i & (~fifo_empty);

FIFO fifo_0(
    // Inputs
    .CLK(clk_i),
    .DATA(data_to_fifo),
    .RE(fifo_re),
    .RESET_N(resetn_i),
    .WE(fifo_we),
    // Outputs
    .DVLD(fifo_dvld),
    .EMPTY(fifo_empty),
    .AFULL(fifo_afull),
    .FULL(),
    .Q(data_in_o)

     );
endmodule

