module cliff_classic (
  output reg ds,
  output reg rd,
  input wire clk,
  input wire go,
  input wire rst_n,
  input wire ws
);

  // state bits
  parameter
  IDLE_BIT = 0,
  DLY_BIT = 1,
  DONE_BIT = 2,
  READ_BIT = 3;

  parameter
  IDLE = 4'b1<<IDLE_BIT,
  DLY  = 4'b1<<DLY_BIT,
  DONE = 4'b1<<DONE_BIT,
  READ = 4'b1<<READ_BIT,
  XXX  = 4'bx;

  reg [3:0] state;
  reg [3:0] nextstate;

  // comb always block
  always @* begin
    nextstate = XXX; // default to x because default_state_is_x is set
    case (1'b1) // synopsys parallel_case full_case
      state[IDLE_BIT]: begin
        if (go) begin
          nextstate = READ;
        end
        else begin
          nextstate = IDLE;
        end
      end
      state[DLY_BIT]: begin
        if (ws) begin
          nextstate = READ;
        end
        else begin
          nextstate = DONE;
        end
      end
      state[DONE_BIT]: begin
        begin
          nextstate = IDLE;
        end
      end
      state[READ_BIT]: begin
        begin
          nextstate = DLY;
        end
      end
    endcase
  end

  // sequential always block
  always @(posedge clk or negedge rst_n) begin
    if (!rst_n)
      state <= IDLE;
    else
      state <= nextstate;
  end

  // datapath sequential always block
  always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      ds <= 0;
      rd <= 0;
    end
    else begin
      ds <= 0; // default
      rd <= 0; // default
      case (1'b1) // synopsys parallel_case full_case
        nextstate[IDLE_BIT]: begin
          ; // case must be complete for onehot
        end
        nextstate[DLY_BIT]: begin
          rd <= 1;
        end
        nextstate[DONE_BIT]: begin
          ds <= 1;
        end
        nextstate[READ_BIT]: begin
          rd <= 1;
        end
      endcase
    end
  end

  // This code allows you to see state names in simulation
  `ifndef SYNTHESIS
  reg [31:0] statename;
  always @* begin
    case (1'b1)
      state[IDLE_BIT]:
        statename = "IDLE";
      state[DLY_BIT]:
        statename = "DLY";
      state[DONE_BIT]:
        statename = "DONE";
      state[READ_BIT]:
        statename = "READ";
      default:
        statename = "XXXX";
    endcase
  end
  `endif

endmodule