data/full_repos/permissive/418284997/src/blocks/uart.v
data/verilator_xmls/4fa518a6-e78c-48a6-b0ac-718ded191977.xml
module uart #(
    parameter COMPARE = 2
  ) (
    input wire clk_i,
    input wire RX,
    input wire [7:0] TXbuffer_i,
    input wire TXstart_i,

    output wire TX,
    output reg [7:0] RXbuffer_o = 0,
    output reg RXready_o = 0,
    output wire TXbusy_o
  );

  localparam TICK_BITS = $clog2(COMPARE + 1);



  reg [TICK_BITS-1:0] tx_acc = 0;
  reg tx_tick = 0;



  reg [3:0] TXstate = 0;
  wire TXready = (TXstate==0);
  assign TXbusy_o = ~TXready;

  reg [7:0] TXshift = 0;

  always @(negedge clk_i) begin

    if(TXready & TXstart_i) TXshift <= TXbuffer_i;
    else if(TXstate[3] & tx_tick) TXshift <= (TXshift >> 1);

    if (TXstate == 4'b0000) tx_acc <= 0;
    else begin
      if (tx_acc == COMPARE) begin
        tx_tick <= 1'b1;
        tx_acc <= 0;
      end else begin
        tx_tick <= 0;
        tx_acc <= tx_acc + 1'b1;
      end
    end

    case(TXstate)
      4'b0000: if(TXstart_i)  TXstate <= 4'b0100;
      4'b0100: if(tx_tick) TXstate <= 4'b1000;
      4'b1000: if(tx_tick) TXstate <= 4'b1001;
      4'b1001: if(tx_tick) TXstate <= 4'b1010;
      4'b1010: if(tx_tick) TXstate <= 4'b1011;
      4'b1011: if(tx_tick) TXstate <= 4'b1100;
      4'b1100: if(tx_tick) TXstate <= 4'b1101;
      4'b1101: if(tx_tick) TXstate <= 4'b1110;
      4'b1110: if(tx_tick) TXstate <= 4'b1111;
      4'b1111: if(tx_tick) TXstate <= 4'b0001;
      4'b0001: if(tx_tick) TXstate <= 4'b0000;
      default: if(tx_tick) TXstate <= 4'b0000;
    endcase
  end

  assign TX = (TXstate < 4) | (TXstate[3] & TXshift[0]);



  reg [3:0] RXstate = 0;
  reg [TICK_BITS-1:0] rx_acc = 0;
  reg rx_tick = 0;

  always @(negedge clk_i) begin

    case (RXstate)
      4'b0000: if (~RX) RXstate <= 4'b1000;
      4'b1000: if (rx_tick) RXstate <= 4'b1001;
      4'b1001: if (rx_tick) RXstate <= 4'b1010;
      4'b1010: if (rx_tick) RXstate <= 4'b1011;
      4'b1011: if (rx_tick) RXstate <= 4'b1100;
      4'b1100: if (rx_tick) RXstate <= 4'b1101;
      4'b1101: if (rx_tick) RXstate <= 4'b1110;
      4'b1110: if (rx_tick) RXstate <= 4'b1111;
      4'b1111: if (rx_tick) RXstate <= 4'b0001;
      4'b0001: if (rx_tick) RXstate <= 4'b0000;
      default: RXstate <= 4'b0000;
    endcase

    if (RXstate == 4'b0000) rx_acc <= 0;
    else begin
      if (rx_acc == COMPARE) begin
        rx_tick <= 1'b1;
        rx_acc <= 0;
      end else begin
        rx_tick <= 0;
        rx_acc <= rx_acc + 1'b1;
      end
    end

    if (rx_tick && RXstate[3]) RXbuffer_o <= {RX, RXbuffer_o[7:1]};
    RXready_o <= (rx_tick && RXstate == 4'b0001);
  end

endmodule
module uart #(
    parameter COMPARE = 2
  ) (
    input wire clk_i,
    input wire RX,
    input wire [7:0] TXbuffer_i,
    input wire TXstart_i,

    output wire TX,
    output reg [7:0] RXbuffer_o = 0,
    output reg RXready_o = 0,
    output wire TXbusy_o
  );


  localparam TICK_BITS = $clog2(COMPARE + 1);



  reg [TICK_BITS-1:0] tx_acc = 0;
  reg tx_tick = 0;



  reg [3:0] TXstate = 0;
  wire TXready = (TXstate==0);
  assign TXbusy_o = ~TXready;

  reg [7:0] TXshift = 0;

  always @(negedge clk_i) begin

    if(TXready & TXstart_i) TXshift <= TXbuffer_i;
    else if(TXstate[3] & tx_tick) TXshift <= (TXshift >> 1);

    if (TXstate == 4'b0000) tx_acc <= 0;
    else begin
      if (tx_acc == COMPARE) begin
        tx_tick <= 1'b1;
        tx_acc <= 0;
      end else begin
        tx_tick <= 0;
        tx_acc <= tx_acc + 1'b1;
      end
    end

    case(TXstate)
      4'b0000: if(TXstart_i)  TXstate <= 4'b0100;
      4'b0100: if(tx_tick) TXstate <= 4'b1000;
      4'b1000: if(tx_tick) TXstate <= 4'b1001;
      4'b1001: if(tx_tick) TXstate <= 4'b1010;
      4'b1010: if(tx_tick) TXstate <= 4'b1011;
      4'b1011: if(tx_tick) TXstate <= 4'b1100;
      4'b1100: if(tx_tick) TXstate <= 4'b1101;
      4'b1101: if(tx_tick) TXstate <= 4'b1110;
      4'b1110: if(tx_tick) TXstate <= 4'b1111;
      4'b1111: if(tx_tick) TXstate <= 4'b0001;
      4'b0001: if(tx_tick) TXstate <= 4'b0000;
      default: if(tx_tick) TXstate <= 4'b0000;
    endcase
  end

  assign TX = (TXstate < 4) | (TXstate[3] & TXshift[0]);



  reg [3:0] RXstate = 0;
  reg [TICK_BITS-1:0] rx_acc = 0;
  reg rx_tick = 0;

  always @(negedge clk_i) begin

    case (RXstate)
      4'b0000: if (~RX) RXstate <= 4'b1000;
      4'b1000: if (rx_tick) RXstate <= 4'b1001;
      4'b1001: if (rx_tick) RXstate <= 4'b1010;
      4'b1010: if (rx_tick) RXstate <= 4'b1011;
      4'b1011: if (rx_tick) RXstate <= 4'b1100;
      4'b1100: if (rx_tick) RXstate <= 4'b1101;
      4'b1101: if (rx_tick) RXstate <= 4'b1110;
      4'b1110: if (rx_tick) RXstate <= 4'b1111;
      4'b1111: if (rx_tick) RXstate <= 4'b0001;
      4'b0001: if (rx_tick) RXstate <= 4'b0000;
      default: RXstate <= 4'b0000;
    endcase

    if (RXstate == 4'b0000) rx_acc <= 0;
    else begin
      if (rx_acc == COMPARE) begin
        rx_tick <= 1'b1;
        rx_acc <= 0;
      end else begin
        rx_tick <= 0;
        rx_acc <= rx_acc + 1'b1;
      end
    end

    if (rx_tick && RXstate[3]) RXbuffer_o <= {RX, RXbuffer_o[7:1]};
    RXready_o <= (rx_tick && RXstate == 4'b0001);
  end

endmodule