library ieee;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;

entity cliff_classic is
port (
  ds : out STD_LOGIC;
  rd : out STD_LOGIC;
  clk : in STD_LOGIC;
  go : in STD_LOGIC;
  rst_n : in STD_LOGIC;
  ws : in STD_LOGIC
);
end cliff_classic;

architecture fizzim of cliff_classic is

-- state bits
subtype state_type is STD_LOGIC_VECTOR(2 downto 0);

constant IDLE: state_type:="000"; -- extra=0 rd=0 ds=0 
constant DLY: state_type:="010"; -- extra=0 rd=1 ds=0 
constant DONE: state_type:="001"; -- extra=0 rd=0 ds=1 
constant READ: state_type:="110"; -- extra=1 rd=1 ds=0 
constant XXX: state_type:="XXX";

signal state,nextstate: state_type;
signal ds_fzm: STD_LOGIC;
signal rd_fzm: STD_LOGIC;

-- comb always block
begin
  COMB: process(state,clk,go,rst_n,ws) begin
    nextstate <= XXX; -- default to x because default_state_is_x is set
    case state is
      when IDLE =>
        if (go='1') then
          nextstate <= READ;
        else
          nextstate <= IDLE;
        end if;

      when DLY  =>
        if (ws='1') then
          nextstate <= READ;
        else
          nextstate <= DONE;
        end if;

      when DONE =>
        nextstate <= IDLE;

      when READ =>
        nextstate <= DLY;

      when others =>

    end case;
  end process;

  -- Assign reg'd outputs to state bits
  ds_fzm <= state(0);
  rd_fzm <= state(1);

  -- Port renames for vhdl
  ds <= ds_fzm;
  rd <= rd_fzm;

  -- sequential always block
  FF: process(clk,rst_n,nextstate) begin
    if (rst_n='0') then
      state <= IDLE;
    elsif (rising_edge(clk)) then
      state <= nextstate;
    end if;
  end process;
end fizzim;