/* threeOnes implements an FSM that outputs a 1 on the 1-bit output (detect)
 * when three consecutive 1's are seen on the 1-bit input stream (w). Also
 * takes 1-bit clock (clk) and 1-bit reset (reset) inputs.
 */
module threeOnes (clk, reset, w, detect);
  input  logic clk, reset, w;
  output logic detect;

  // State encoding - state names represent how many 1's have been seen.
  // Signals ps = "Present State" and ns = "Next State".
  enum {zero, one, two} ps, ns;

  // Next State logic - "advance" if w == 1, otherwise "reset" to state zero.
  always_comb
    case (ps)
      zero:   ns = w ? one : zero;
      one:    ns = w ? two : zero;
      two:    ns = w ? two : zero;
      default:  ns = zero;
    endcase

  // Output logic - only if 3rd one is seen
  assign detect = (ps == two) && w;

  // Sequential logic (DFFs) - reset state is zero.
  always_ff @(posedge clk)
    ps <= reset ? zero : ns;

endmodule  // threeOnes