data/full_repos/permissive/208636171/fpga/usb/usb_fs_rx.v
 line:24: before: "="
data/verilator_xmls/e6670686-4878-4d25-ad33-78b0aa76e5bc.xml
module usb_fs_rx (

  input clk_48mhz,
  input reset,


  input dp,
  input dn,


  output bit_strobe,


  output pkt_start,


  output pkt_end,


  output [3:0] pid,
  output reg [6:0] addr = 0,
  output reg [3:0] endp = 0,
  output reg [10:0] frame_num = 0,


  output rx_data_put,
  output [7:0] rx_data,


  output valid_packet
);
  wire clk = clk_48mhz;









  




  reg [3:0] dpair_q = 0;

  always @(posedge clk) begin
      dpair_q[3:0] <= {dpair_q[1:0], dp, dn};
  end






  reg [2:0] line_state = 0;
  localparam  DT = 3'b100;
  localparam  DJ = 3'b010;
  localparam  DK = 3'b001;
  localparam SE0 = 3'b000;
  localparam SE1 = 3'b011;

  wire [1:0] dpair = dpair_q[3:2];

  always @(posedge clk) begin
      case (line_state)


          DT : begin
              case (dpair)
                  2'b10 : line_state <= DJ;
                  2'b01 : line_state <= DK;
                  2'b00 : line_state <= SE0;
                  2'b11 : line_state <= SE1;
              endcase
          end



          DJ  : if (dpair != 2'b10) line_state <= DT;
          DK  : if (dpair != 2'b01) line_state <= DT;
          SE0 : if (dpair != 2'b00) line_state <= DT;
          SE1 : if (dpair != 2'b11) line_state <= DT;        


          default : line_state <= DT;
      endcase
  end






  reg [1:0] bit_phase = 0;

  wire line_state_valid = (bit_phase == 1);
  assign bit_strobe = (bit_phase == 2);

  always @(posedge clk) begin

      if (line_state == DT) begin
          bit_phase <= 0;

      end else begin
          bit_phase <= bit_phase + 1;
      end
  end





  reg [5:0] line_history = 0;
  reg packet_valid = 0;
  reg next_packet_valid;
  wire packet_start = next_packet_valid && !packet_valid;
  wire packet_end = !next_packet_valid && packet_valid;

  always @* begin
    if (line_state_valid) begin

      if (!packet_valid && line_history[5:0] == 6'b100101) begin
        next_packet_valid <= 1;
      end
 

      else if (packet_valid && line_history[3:0] == 4'b0000) begin
        next_packet_valid <= 0;

      end else begin
        next_packet_valid <= packet_valid;
      end
    end else begin
      next_packet_valid <= packet_valid;
    end
  end

  always @(posedge clk) begin
    if (reset) begin
      line_history <= 6'b101010;
      packet_valid <= 0;
    end else begin

      if (line_state_valid) begin
        line_history[5:0] <= {line_history[3:0], line_state[1:0]};
      end
    end
    packet_valid <= next_packet_valid;
  end





  reg dvalid_raw;
  reg din;

  always @* begin
    case (line_history[3:0])
      4'b0101 : din <= 1;
      4'b0110 : din <= 0;
      4'b1001 : din <= 0;
      4'b1010 : din <= 1;
      default : din <= 0;
    endcase
 
    if (packet_valid && line_state_valid) begin
      case (line_history[3:0])
        4'b0101 : dvalid_raw <= 1;
        4'b0110 : dvalid_raw <= 1;
        4'b1001 : dvalid_raw <= 1;
        4'b1010 : dvalid_raw <= 1;
        default : dvalid_raw <= 0;
      endcase
    end else begin
      dvalid_raw <= 0;
    end
  end

  reg [5:0] bitstuff_history = 0;

  always @(posedge clk) begin
    if (reset || packet_end) begin
      bitstuff_history <= 6'b000000;
    end else begin
      if (dvalid_raw) begin
        bitstuff_history <= {bitstuff_history[4:0], din};
      end
    end  
  end

  wire dvalid = dvalid_raw && !(bitstuff_history == 6'b111111);






  reg [8:0] full_pid = 0;
  wire pid_valid = full_pid[4:1] == ~full_pid[8:5];
  wire pid_complete = full_pid[0];

  always @(posedge clk) begin
    if (packet_start) begin
      full_pid <= 9'b100000000;
    end

    if (dvalid && !pid_complete) begin
        full_pid <= {din, full_pid[8:1]};
    end
  end




  reg [4:0] crc5 = 0;
  wire crc5_valid = crc5 == 5'b01100;
  wire crc5_invert = din ^ crc5[4];
  always @(posedge clk) begin
    if (packet_start) begin
      crc5 <= 5'b11111;
    end

    if (dvalid && pid_complete) begin
      crc5[4] <= crc5[3];
      crc5[3] <= crc5[2];
      crc5[2] <= crc5[1] ^ crc5_invert;
      crc5[1] <= crc5[0];
      crc5[0] <= crc5_invert;
    end
  end




  reg [15:0] crc16 = 0;
  wire crc16_valid = crc16 == 16'b1000000000001101;
  wire crc16_invert = din ^ crc16[15];  

  always @(posedge clk) begin
    if (packet_start) begin
      crc16 <= 16'b1111111111111111;
    end

    if (dvalid && pid_complete) begin
      crc16[15] <= crc16[14] ^ crc16_invert;
      crc16[14] <= crc16[13];
      crc16[13] <= crc16[12];
      crc16[12] <= crc16[11];
      crc16[11] <= crc16[10];
      crc16[10] <= crc16[9];
      crc16[9] <= crc16[8];
      crc16[8] <= crc16[7];
      crc16[7] <= crc16[6];
      crc16[6] <= crc16[5];
      crc16[5] <= crc16[4];
      crc16[4] <= crc16[3];
      crc16[3] <= crc16[2];
      crc16[2] <= crc16[1] ^ crc16_invert;
      crc16[1] <= crc16[0];
      crc16[0] <= crc16_invert;
    end
  end




  wire pkt_is_token = full_pid[2:1] == 2'b01;
  wire pkt_is_data = full_pid[2:1] == 2'b11;
  wire pkt_is_handshake = full_pid[2:1] == 2'b10;




  assign valid_packet = pid_valid && (
    (pkt_is_handshake) || 
    (pkt_is_data && crc16_valid) ||
    (pkt_is_token && crc5_valid)
  );
  

  reg [11:0] token_payload = 0;
  wire token_payload_done = token_payload[0];

  always @(posedge clk) begin
    if (packet_start) begin
      token_payload <= 12'b100000000000;
    end

    if (dvalid && pid_complete && pkt_is_token && !token_payload_done) begin
      token_payload <= {din, token_payload[11:1]};
    end
  end

  always @(posedge clk) begin
    if (token_payload_done && pkt_is_token) begin
      addr <= token_payload[7:1];
      endp <= token_payload[11:8];
      frame_num <= token_payload[11:1];
    end
  end

  assign pkt_start = packet_start;
  assign pkt_end = packet_end; 
  assign pid = full_pid[4:1]; 



  




  reg [8:0] rx_data_buffer = 0;
  wire rx_data_buffer_full = rx_data_buffer[0];
  assign rx_data_put = rx_data_buffer_full;
  assign rx_data = rx_data_buffer[8:1];

  always @(posedge clk) begin
    if (packet_start || rx_data_buffer_full) begin
      rx_data_buffer <= 9'b100000000;
    end

    if (dvalid && pid_complete && pkt_is_data) begin
        rx_data_buffer <= {din, rx_data_buffer[8:1]};
    end
  end

endmodule
module usb_fs_rx (

  input clk_48mhz,
  input reset,


  input dp,
  input dn,


  output bit_strobe,


  output pkt_start,


  output pkt_end,


  output [3:0] pid,
  output reg [6:0] addr = 0,
  output reg [3:0] endp = 0,
  output reg [10:0] frame_num = 0,


  output rx_data_put,
  output [7:0] rx_data,


  output valid_packet
);

  wire clk = clk_48mhz;









  




  reg [3:0] dpair_q = 0;

  always @(posedge clk) begin
      dpair_q[3:0] <= {dpair_q[1:0], dp, dn};
  end






  reg [2:0] line_state = 0;
  localparam  DT = 3'b100;
  localparam  DJ = 3'b010;
  localparam  DK = 3'b001;
  localparam SE0 = 3'b000;
  localparam SE1 = 3'b011;

  wire [1:0] dpair = dpair_q[3:2];

  always @(posedge clk) begin
      case (line_state)


          DT : begin
              case (dpair)
                  2'b10 : line_state <= DJ;
                  2'b01 : line_state <= DK;
                  2'b00 : line_state <= SE0;
                  2'b11 : line_state <= SE1;
              endcase
          end



          DJ  : if (dpair != 2'b10) line_state <= DT;
          DK  : if (dpair != 2'b01) line_state <= DT;
          SE0 : if (dpair != 2'b00) line_state <= DT;
          SE1 : if (dpair != 2'b11) line_state <= DT;        


          default : line_state <= DT;
      endcase
  end






  reg [1:0] bit_phase = 0;

  wire line_state_valid = (bit_phase == 1);
  assign bit_strobe = (bit_phase == 2);

  always @(posedge clk) begin

      if (line_state == DT) begin
          bit_phase <= 0;

      end else begin
          bit_phase <= bit_phase + 1;
      end
  end





  reg [5:0] line_history = 0;
  reg packet_valid = 0;
  reg next_packet_valid;
  wire packet_start = next_packet_valid && !packet_valid;
  wire packet_end = !next_packet_valid && packet_valid;

  always @* begin
    if (line_state_valid) begin

      if (!packet_valid && line_history[5:0] == 6'b100101) begin
        next_packet_valid <= 1;
      end
 

      else if (packet_valid && line_history[3:0] == 4'b0000) begin
        next_packet_valid <= 0;

      end else begin
        next_packet_valid <= packet_valid;
      end
    end else begin
      next_packet_valid <= packet_valid;
    end
  end

  always @(posedge clk) begin
    if (reset) begin
      line_history <= 6'b101010;
      packet_valid <= 0;
    end else begin

      if (line_state_valid) begin
        line_history[5:0] <= {line_history[3:0], line_state[1:0]};
      end
    end
    packet_valid <= next_packet_valid;
  end





  reg dvalid_raw;
  reg din;

  always @* begin
    case (line_history[3:0])
      4'b0101 : din <= 1;
      4'b0110 : din <= 0;
      4'b1001 : din <= 0;
      4'b1010 : din <= 1;
      default : din <= 0;
    endcase
 
    if (packet_valid && line_state_valid) begin
      case (line_history[3:0])
        4'b0101 : dvalid_raw <= 1;
        4'b0110 : dvalid_raw <= 1;
        4'b1001 : dvalid_raw <= 1;
        4'b1010 : dvalid_raw <= 1;
        default : dvalid_raw <= 0;
      endcase
    end else begin
      dvalid_raw <= 0;
    end
  end

  reg [5:0] bitstuff_history = 0;

  always @(posedge clk) begin
    if (reset || packet_end) begin
      bitstuff_history <= 6'b000000;
    end else begin
      if (dvalid_raw) begin
        bitstuff_history <= {bitstuff_history[4:0], din};
      end
    end  
  end

  wire dvalid = dvalid_raw && !(bitstuff_history == 6'b111111);






  reg [8:0] full_pid = 0;
  wire pid_valid = full_pid[4:1] == ~full_pid[8:5];
  wire pid_complete = full_pid[0];

  always @(posedge clk) begin
    if (packet_start) begin
      full_pid <= 9'b100000000;
    end

    if (dvalid && !pid_complete) begin
        full_pid <= {din, full_pid[8:1]};
    end
  end




  reg [4:0] crc5 = 0;
  wire crc5_valid = crc5 == 5'b01100;
  wire crc5_invert = din ^ crc5[4];
  always @(posedge clk) begin
    if (packet_start) begin
      crc5 <= 5'b11111;
    end

    if (dvalid && pid_complete) begin
      crc5[4] <= crc5[3];
      crc5[3] <= crc5[2];
      crc5[2] <= crc5[1] ^ crc5_invert;
      crc5[1] <= crc5[0];
      crc5[0] <= crc5_invert;
    end
  end




  reg [15:0] crc16 = 0;
  wire crc16_valid = crc16 == 16'b1000000000001101;
  wire crc16_invert = din ^ crc16[15];  

  always @(posedge clk) begin
    if (packet_start) begin
      crc16 <= 16'b1111111111111111;
    end

    if (dvalid && pid_complete) begin
      crc16[15] <= crc16[14] ^ crc16_invert;
      crc16[14] <= crc16[13];
      crc16[13] <= crc16[12];
      crc16[12] <= crc16[11];
      crc16[11] <= crc16[10];
      crc16[10] <= crc16[9];
      crc16[9] <= crc16[8];
      crc16[8] <= crc16[7];
      crc16[7] <= crc16[6];
      crc16[6] <= crc16[5];
      crc16[5] <= crc16[4];
      crc16[4] <= crc16[3];
      crc16[3] <= crc16[2];
      crc16[2] <= crc16[1] ^ crc16_invert;
      crc16[1] <= crc16[0];
      crc16[0] <= crc16_invert;
    end
  end




  wire pkt_is_token = full_pid[2:1] == 2'b01;
  wire pkt_is_data = full_pid[2:1] == 2'b11;
  wire pkt_is_handshake = full_pid[2:1] == 2'b10;




  assign valid_packet = pid_valid && (
    (pkt_is_handshake) || 
    (pkt_is_data && crc16_valid) ||
    (pkt_is_token && crc5_valid)
  );
  

  reg [11:0] token_payload = 0;
  wire token_payload_done = token_payload[0];

  always @(posedge clk) begin
    if (packet_start) begin
      token_payload <= 12'b100000000000;
    end

    if (dvalid && pid_complete && pkt_is_token && !token_payload_done) begin
      token_payload <= {din, token_payload[11:1]};
    end
  end

  always @(posedge clk) begin
    if (token_payload_done && pkt_is_token) begin
      addr <= token_payload[7:1];
      endp <= token_payload[11:8];
      frame_num <= token_payload[11:1];
    end
  end

  assign pkt_start = packet_start;
  assign pkt_end = packet_end; 
  assign pid = full_pid[4:1]; 



  




  reg [8:0] rx_data_buffer = 0;
  wire rx_data_buffer_full = rx_data_buffer[0];
  assign rx_data_put = rx_data_buffer_full;
  assign rx_data = rx_data_buffer[8:1];

  always @(posedge clk) begin
    if (packet_start || rx_data_buffer_full) begin
      rx_data_buffer <= 9'b100000000;
    end

    if (dvalid && pid_complete && pkt_is_data) begin
        rx_data_buffer <= {din, rx_data_buffer[8:1]};
    end
  end

endmodule