// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// USB Full-Speed Device Interface core internals
//
//

`include "prim_assert.sv"

// This module runs on the 48MHz USB clock
module usbdev_usbif  #(
  parameter int NEndpoints = 12,
  parameter int AVFifoWidth = 4,
  parameter int RXFifoWidth = 4,
  parameter int MaxPktSizeByte = 64,
  parameter int NBuf = 4,
  parameter int SramAw = 4,
  localparam int NBufWidth = $clog2(NBuf), // derived parameter
  localparam int PktW = $clog2(MaxPktSizeByte) // derived parameter
) (
  input  logic                     clk_48mhz_i, // 48MHz USB clock
  input  logic                     rst_ni,

  // Pins (synchronous)
  input  logic                     usb_d_i,
  input  logic                     usb_dp_i,
  input  logic                     usb_dn_i,

  output logic                     usb_d_o,
  output logic                     usb_se0_o,
  output logic                     usb_oe_o,

  output logic                     usb_pullup_en_o,
  input  logic                     usb_sense_i,

  // receive (OUT or SETUP) side
  input  logic [NEndpoints-1:0]    rx_setup_i,
  input  logic [NEndpoints-1:0]    rx_out_i,
  input  logic [NEndpoints-1:0]    rx_stall_i,
  input  logic                     av_rvalid_i,
  output logic                     av_rready_o,
  input  logic [AVFifoWidth - 1: 0]av_rdata_i,
  output logic                     event_av_empty_o,

  output logic                     rx_wvalid_o,
  input  logic                     rx_wready_i,
  output logic [RXFifoWidth - 1:0] rx_wdata_o,
  output logic                     event_rx_full_o,
  output logic                     setup_received_o,
  output logic [3:0]               out_endpoint_o,
  output logic                     out_endpoint_val_o,

  // transmit (IN) side
  input  logic [NBufWidth - 1:0]   in_buf_i,
  input  logic [PktW:0]            in_size_i,
  input  logic [NEndpoints-1:0]    in_stall_i,
  input  logic [NEndpoints-1:0]    in_rdy_i,
  output logic                     set_sent_o,
  output logic [3:0]               in_endpoint_o,
  output logic                     in_endpoint_val_o,

  // memory interface
  output logic                     mem_req_o,
  output logic                     mem_write_o,
  output logic [SramAw-1:0]        mem_addr_o,
  output logic [31:0]              mem_wdata_o,
  input  logic [31:0]              mem_rdata_i,

  // control
  input  logic                     enable_i,
  input  logic [6:0]               devaddr_i,
  output logic                     clr_devaddr_o,
  input  logic [NEndpoints-1:0]    ep_iso_i,
  input  logic                     cfg_eop_single_bit_i, // 1: detect a single SE0 bit as EOP
  input  logic                     cfg_rx_differential_i, // 1: use differential rx data on usb_d_i
  input  logic                     tx_osc_test_mode_i, // Oscillator test mode: constant JK output
  input  logic [NEndpoints-1:0]    data_toggle_clear_i, // Clear the data toggles for an EP

  // status
  output logic                     frame_start_o,
  output logic [10:0]              frame_o,
  output logic [2:0]               link_state_o,
  output logic                     link_disconnect_o,
  output logic                     link_connect_o,
  output logic                     link_reset_o,
  output logic                     link_active_o,
  output logic                     link_suspend_o,
  output logic                     link_resume_o,
  output logic                     link_in_err_o,
  output logic                     link_out_err_o,
  output logic                     host_lost_o,
  output logic                     rx_crc_err_o,
  output logic                     rx_pid_err_o,
  output logic                     rx_bitstuff_err_o
);

  assign usb_pullup_en_o = enable_i;

  // OUT or SETUP direction
  logic [PktW:0]                     out_max_used_d, out_max_used_q;
  logic [PktW-1:0]                   out_ep_put_addr;
  logic [7:0]                        out_ep_data;

  logic [3:0]                        out_ep_current;
  logic                              out_ep_data_put, out_ep_acked, out_ep_rollback;
  logic                              current_setup, all_out_blocked, out_ep_newpkt;
  logic [NEndpoints-1:0]             out_ep_setup, out_ep_full, out_ep_stall;
  logic [NEndpoints-1:0]             setup_blocked, out_blocked;
  logic [31:0]                       wdata;
  logic                              mem_read;
  logic [SramAw-1:0]                 mem_waddr, mem_raddr;
  logic                              link_reset;
  logic                              sof_valid;

  // Make sure out_endpoint_o can safely be used to index signals of NEndpoints width.
  assign out_endpoint_val_o = int'(out_ep_current) < NEndpoints;
  assign out_endpoint_o     = out_endpoint_val_o ? out_ep_current : '0;

  assign link_reset_o   = link_reset;
  assign clr_devaddr_o  = ~enable_i | link_reset;
  assign frame_start_o  = sof_valid;
  assign link_out_err_o = out_ep_rollback;

  always_comb begin
    if (out_ep_acked || out_ep_rollback) begin
      out_max_used_d = 0;

    end else if (out_ep_data_put) begin
      // In the normal case <MaxPktSizeByte this is out_max_used_q <= out_ep_put_addr
      // Following all ones out_max_used_q will get 1,00..00 and 1,00..01 to cover
      // one and two bytes of the CRC overflowing, then stick at 1,00..01
      if (int'(out_max_used_q) < MaxPktSizeByte - 1) begin
        out_max_used_d = {1'b0, out_ep_put_addr};
      end else if (int'(out_max_used_q) < MaxPktSizeByte + 1) begin
        out_max_used_d = out_max_used_q + 1;
      end else begin
        out_max_used_d = out_max_used_q;
      end

    end else begin
      out_max_used_d = out_max_used_q;
    end
  end // always_comb

  // don't write if the address has wrapped (happens for two CRC bytes after max data)
  logic std_write_d, std_write_q;
  assign std_write_d = out_ep_data_put & ((int'(out_max_used_q) < MaxPktSizeByte - 1) &
      (out_ep_put_addr[1:0] == 2'b11));

  always_ff @(posedge clk_48mhz_i or negedge rst_ni) begin
    if (!rst_ni) begin
      out_max_used_q <= '0;
      wdata          <= '0;
      std_write_q    <= 1'b0;
    end else begin
      out_max_used_q <= out_max_used_d;
      std_write_q    <= std_write_d;
      if (out_ep_data_put) begin
        unique case (out_ep_put_addr[1:0])
          0: begin
            wdata[7:0] <= out_ep_data;
          end
          1: begin
            wdata[15:8] <= out_ep_data;
          end
          2: begin
            wdata[23:16] <= out_ep_data;
          end
          3: begin
            wdata[31:24] <= out_ep_data;
          end
          default: begin
            wdata[7:0] <= out_ep_data;
          end
        endcase
      end
    end
  end // always_ff @ (posedge clk_48mhz_i)

  // need extra write at end if packet not multiple of 4 bytes
  assign mem_write_o = std_write_q |
                       (~out_max_used_q[PktW] & (out_max_used_q[1:0] != 2'b11) & out_ep_acked);
  assign mem_waddr = {av_rdata_i, out_max_used_q[PktW-1:2]};
  assign mem_wdata_o = wdata;
  assign mem_addr_o = mem_write_o ? mem_waddr : mem_raddr;
  assign mem_req_o = mem_read | mem_write_o;
  assign current_setup = out_ep_setup[out_endpoint_o];

  logic [PktW:0] out_max_minus1;
  // -2 for CRC bytes but +1 for zero-based address to size
  assign out_max_minus1 = out_max_used_q - 1;

  assign rx_wdata_o = {
      out_endpoint_o,
      current_setup,
      out_max_minus1,
      av_rdata_i
  };
  assign rx_wvalid_o = out_ep_acked & ~all_out_blocked;
  // Pop the available fifo after the write that used the previous value
  always_ff @(posedge clk_48mhz_i or negedge rst_ni) begin
    if (!rst_ni) begin
      av_rready_o <= 1'b0;
    end else begin
      av_rready_o <= rx_wvalid_o;
    end
  end

  // full here covers the software blocking by clearing the enable
  assign setup_blocked = out_ep_setup & ~rx_setup_i;
  assign out_blocked = ~out_ep_setup & ~rx_out_i;
  // full also covers being blocked because the hardware can't take any transaction
  assign all_out_blocked = (~rx_wready_i) | (~av_rvalid_i);
  // These are used to raise appropriate interrupt
  assign event_av_empty_o = out_ep_newpkt & (~av_rvalid_i);
  assign event_rx_full_o = out_ep_newpkt & (~rx_wready_i);

  assign out_ep_full = {NEndpoints{all_out_blocked}} | setup_blocked | out_blocked;
  assign out_ep_stall = rx_stall_i;

  // Need to clear IN read if a SETUP is received because it may use the IN channel
  // This will not trigger, if the AV Buffer is empty, in that case we have replied
  // with a NAK, which is illegal anyway
  assign setup_received_o = current_setup & rx_wvalid_o;

  // IN (device to host) transfers
  logic                  in_ep_xfr_end, in_ep_data_get, in_data_done, in_ep_newpkt, pkt_start_rd;
  logic [NEndpoints-1:0] in_ep_data_done;
  logic [PktW-1:0]       in_ep_get_addr;
  logic [7:0]            in_ep_data;
  logic [3:0]            in_ep_current;

  // Make sure in_endpoint_o can safely be used to index signals of NEndpoints width.
  assign in_endpoint_val_o = int'(in_ep_current) < NEndpoints;
  assign in_endpoint_o     = in_endpoint_val_o ? in_ep_current : '0;

  // The protocol engine will automatically generate done for a full-length packet
  // Note: this does the correct thing for sending zero length packets
  assign in_data_done = {1'b0, in_ep_get_addr} == in_size_i;
  always_comb begin
    in_ep_data_done = '0;
    in_ep_data_done[in_endpoint_o] = in_data_done;
  end

  // Need extra read at start of packet to get the first word of data
  // Delay by one cycle from the in_endpoint update
  always_ff @(posedge clk_48mhz_i or negedge rst_ni) begin
    if (!rst_ni) begin
      pkt_start_rd <= 1'b0;
    end else begin
      pkt_start_rd <= in_ep_newpkt;
    end
  end

  assign mem_raddr = {in_buf_i,in_ep_get_addr[PktW-1:2]};
  assign mem_read = pkt_start_rd | (in_ep_data_get & (in_ep_get_addr[1:0] == 2'b0));

  assign in_ep_data = in_ep_get_addr[1] ?
                      (in_ep_get_addr[0] ? mem_rdata_i[31:24] : mem_rdata_i[23:16]) :
                      (in_ep_get_addr[0] ? mem_rdata_i[15:8]  : mem_rdata_i[7:0]);
  assign set_sent_o = in_ep_xfr_end;

  logic [10:0]     frame_index_raw;
  logic            rx_jjj_det;

  usb_fs_nb_pe #(
    .NumOutEps      (NEndpoints),
    .NumInEps       (NEndpoints),
    .MaxPktSizeByte (MaxPktSizeByte)
  ) u_usb_fs_nb_pe (
    .clk_48mhz_i           (clk_48mhz_i),
    .rst_ni                (rst_ni),
    .link_reset_i          (link_reset),

    .cfg_eop_single_bit_i  (cfg_eop_single_bit_i),
    .cfg_rx_differential_i (cfg_rx_differential_i),
    .tx_osc_test_mode_i    (tx_osc_test_mode_i),
    .data_toggle_clear_i   (data_toggle_clear_i),

    .usb_d_i               (usb_d_i),
    .usb_dp_i              (usb_dp_i),
    .usb_dn_i              (usb_dn_i),
    .usb_d_o               (usb_d_o),
    .usb_se0_o             (usb_se0_o),
    .usb_oe_o              (usb_oe_o),

    .dev_addr_i            (devaddr_i),

    // out endpoint interfaces
    .out_ep_current_o      (out_ep_current),
    .out_ep_newpkt_o       (out_ep_newpkt),
    .out_ep_data_put_o     (out_ep_data_put),
    .out_ep_put_addr_o     (out_ep_put_addr),
    .out_ep_data_o         (out_ep_data),
    .out_ep_acked_o        (out_ep_acked),
    .out_ep_rollback_o     (out_ep_rollback),
    .out_ep_setup_o        (out_ep_setup),
    .out_ep_full_i         (out_ep_full),
    .out_ep_stall_i        (out_ep_stall),
    .out_ep_iso_i          (ep_iso_i),

    // in endpoint interfaces
    .in_ep_current_o       (in_ep_current),
    .in_ep_rollback_o      (link_in_err_o),
    .in_ep_xfr_end_o       (in_ep_xfr_end),
    .in_ep_get_addr_o      (in_ep_get_addr),
    .in_ep_data_get_o      (in_ep_data_get),
    .in_ep_newpkt_o        (in_ep_newpkt),
    .in_ep_stall_i         (in_stall_i),
    .in_ep_has_data_i      (in_rdy_i),
    .in_ep_data_i          (in_ep_data),
    .in_ep_data_done_i     (in_ep_data_done),
    .in_ep_iso_i           (ep_iso_i),

    // rx status
    .rx_jjj_det_o          (rx_jjj_det),

    // error signals
    .rx_crc_err_o          (rx_crc_err_o),
    .rx_pid_err_o          (rx_pid_err_o),
    .rx_bitstuff_err_o     (rx_bitstuff_err_o),

    // sof interface
    .sof_valid_o           (sof_valid),
    .frame_index_o         (frame_index_raw)
  );

  // us_tick ticks for one cycle every us
  logic [5:0]   ns_cnt;
  logic         us_tick;

  assign us_tick = (ns_cnt == 6'd48);
  always_ff @(posedge clk_48mhz_i or negedge rst_ni) begin
    if (!rst_ni) begin
      ns_cnt <= '0;
    end else begin
      if (us_tick) begin
        ns_cnt <= '0;
      end else begin
        ns_cnt <= ns_cnt + 1'b1;
      end
    end
  end

  // Capture frame number (host sends evert 1ms)
  always_ff @(posedge clk_48mhz_i or negedge rst_ni) begin
    if (!rst_ni) begin
      frame_o <= '0;
    end else begin
      if (sof_valid) begin
        frame_o <= frame_index_raw;
      end
    end
  end

  usbdev_linkstate u_usbdev_linkstate (
    .clk_48mhz_i       (clk_48mhz_i),
    .rst_ni            (rst_ni),
    .us_tick_i         (us_tick),
    .usb_sense_i       (usb_sense_i),
    .usb_dp_i          (usb_dp_i),
    .usb_dn_i          (usb_dn_i),
    .usb_oe_i          (usb_oe_o),
    .rx_jjj_det_i      (rx_jjj_det),
    .sof_valid_i       (sof_valid),
    .link_disconnect_o (link_disconnect_o),
    .link_connect_o    (link_connect_o),
    .link_reset_o      (link_reset),
    .link_active_o     (link_active_o),
    .link_suspend_o    (link_suspend_o),
    .link_resume_o     (link_resume_o),
    .link_state_o      (link_state_o),
    .host_lost_o       (host_lost_o)
  );

  ////////////////
  // Assertions //
  ////////////////

endmodule
