-- altera vhdl_input_version vhdl_2008
-- XXX: QSYS Fix (https://www.intel.com/content/www/us/en/support/programmable/articles/000079458.html)

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

use work.math_pkg.all;
use work.rtps_package.all;
use work.ros_package.all;
use work.Fibonacci_package.all;
use work.GoalStatus_package;
use work.GoalStatusArray_package;
use work.CancelGoal_package;

entity Fibonacci_ros_action_client is
    generic (
        ENABLE_FEEDBACK     : std_logic := '1';
        LITTLE_ENDIAN       : std_logic := '0'
    );
    port (
        -- SYSTEM
        clk                         : in std_logic;
        reset                       : in std_logic;
        time                        : in ROS_TIME_TYPE;
        -- *GOAL SERVICE*
        -- DDS READER
        g_start_r                   : out std_logic;
        g_ack_r                     : in std_logic;
        g_opcode_r                  : out DDS_READER_OPCODE_TYPE;
        g_instance_state_r          : out std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0);
        g_view_state_r              : out std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0);
        g_sample_state_r            : out std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0);
        g_instance_handle_r         : out INSTANCE_HANDLE_TYPE;
        g_max_samples_r             : out std_logic_vector(MAX_SAMPLES_WIDTH-1 downto 0);
        g_get_data_r                : out std_logic;
        g_done_r                    : in std_logic;
        g_return_code_r             : in std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
        g_valid_in_r                : in std_logic;
        g_ready_in_r                : out std_logic;
        g_data_in_r                 : in std_logic_vector(WORD_WIDTH-1 downto 0);
        g_last_word_in_r            : in std_logic;
        g_sample_info_r             : in SAMPLE_INFO_TYPE;
        g_sample_info_valid_r       : in std_logic;
        g_sample_info_ack_r         : out std_logic;
        g_eoc_r                     : in std_logic;
        g_status_r                  : in std_logic_vector(STATUS_KIND_WIDTH-1 downto 0);
        -- DDS WRITER
        g_start_w                   : out std_logic;
        g_ack_w                     : in std_logic;
        g_opcode_w                  : out DDS_WRITER_OPCODE_TYPE;
        g_instance_handle_in_w      : out INSTANCE_HANDLE_TYPE;
        g_source_ts_w               : out TIME_TYPE;
        g_max_wait_w                : out DURATION_TYPE;
        g_done_w                    : in std_logic;
        g_return_code_w             : in std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
        g_instance_handle_out_w     : in INSTANCE_HANDLE_TYPE;
        g_valid_out_w               : out std_logic;
        g_ready_out_w               : in std_logic;
        g_data_out_w                : out std_logic_vector(WORD_WIDTH-1 downto 0);
        g_last_word_out_w           : out std_logic;
        g_valid_in_w                : in std_logic;
        g_ready_in_w                : out std_logic;
        g_data_in_w                 : in std_logic_vector(WORD_WIDTH-1 downto 0);
        g_last_word_in_w            : in std_logic;
        g_status_w                  : in std_logic_vector(STATUS_KIND_WIDTH-1 downto 0);
        -- *RESULT SERVICE*
        -- DDS READER
        r_start_r                   : out std_logic;
        r_ack_r                     : in std_logic;
        r_opcode_r                  : out DDS_READER_OPCODE_TYPE;
        r_instance_state_r          : out std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0);
        r_view_state_r              : out std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0);
        r_sample_state_r            : out std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0);
        r_instance_handle_r         : out INSTANCE_HANDLE_TYPE;
        r_max_samples_r             : out std_logic_vector(MAX_SAMPLES_WIDTH-1 downto 0);
        r_get_data_r                : out std_logic;
        r_done_r                    : in std_logic;
        r_return_code_r             : in std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
        r_valid_in_r                : in std_logic;
        r_ready_in_r                : out std_logic;
        r_data_in_r                 : in std_logic_vector(WORD_WIDTH-1 downto 0);
        r_last_word_in_r            : in std_logic;
        r_sample_info_r             : in SAMPLE_INFO_TYPE;
        r_sample_info_valid_r       : in std_logic;
        r_sample_info_ack_r         : out std_logic;
        r_eoc_r                     : in std_logic;
        r_status_r                  : in std_logic_vector(STATUS_KIND_WIDTH-1 downto 0);
        -- DDS WRITER
        r_start_w                   : out std_logic;
        r_ack_w                     : in std_logic;
        r_opcode_w                  : out DDS_WRITER_OPCODE_TYPE;
        r_instance_handle_in_w      : out INSTANCE_HANDLE_TYPE;
        r_source_ts_w               : out TIME_TYPE;
        r_max_wait_w                : out DURATION_TYPE;
        r_done_w                    : in std_logic;
        r_return_code_w             : in std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
        r_instance_handle_out_w     : in INSTANCE_HANDLE_TYPE;
        r_valid_out_w               : out std_logic;
        r_ready_out_w               : in std_logic;
        r_data_out_w                : out std_logic_vector(WORD_WIDTH-1 downto 0);
        r_last_word_out_w           : out std_logic;
        r_valid_in_w                : in std_logic;
        r_ready_in_w                : out std_logic;
        r_data_in_w                 : in std_logic_vector(WORD_WIDTH-1 downto 0);
        r_last_word_in_w            : in std_logic;
        r_status_w                  : in std_logic_vector(STATUS_KIND_WIDTH-1 downto 0);
        -- *CANCEL SERVICE*
        -- DDS READER
        c_start_r                   : out std_logic;
        c_ack_r                     : in std_logic;
        c_opcode_r                  : out DDS_READER_OPCODE_TYPE;
        c_instance_state_r          : out std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0);
        c_view_state_r              : out std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0);
        c_sample_state_r            : out std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0);
        c_instance_handle_r         : out INSTANCE_HANDLE_TYPE;
        c_max_samples_r             : out std_logic_vector(MAX_SAMPLES_WIDTH-1 downto 0);
        c_get_data_r                : out std_logic;
        c_done_r                    : in std_logic;
        c_return_code_r             : in std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
        c_valid_in_r                : in std_logic;
        c_ready_in_r                : out std_logic;
        c_data_in_r                 : in std_logic_vector(WORD_WIDTH-1 downto 0);
        c_last_word_in_r            : in std_logic;
        c_sample_info_r             : in SAMPLE_INFO_TYPE;
        c_sample_info_valid_r       : in std_logic;
        c_sample_info_ack_r         : out std_logic;
        c_eoc_r                     : in std_logic;
        c_status_r                  : in std_logic_vector(STATUS_KIND_WIDTH-1 downto 0);
        -- DDS WRITER
        c_start_w                   : out std_logic;
        c_ack_w                     : in std_logic;
        c_opcode_w                  : out DDS_WRITER_OPCODE_TYPE;
        c_instance_handle_in_w      : out INSTANCE_HANDLE_TYPE;
        c_source_ts_w               : out TIME_TYPE;
        c_max_wait_w                : out DURATION_TYPE;
        c_done_w                    : in std_logic;
        c_return_code_w             : in std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
        c_instance_handle_out_w     : in INSTANCE_HANDLE_TYPE;
        c_valid_out_w               : out std_logic;
        c_ready_out_w               : in std_logic;
        c_data_out_w                : out std_logic_vector(WORD_WIDTH-1 downto 0);
        c_last_word_out_w           : out std_logic;
        c_valid_in_w                : in std_logic;
        c_ready_in_w                : out std_logic;
        c_data_in_w                 : in std_logic_vector(WORD_WIDTH-1 downto 0);
        c_last_word_in_w            : in std_logic;
        c_status_w                  : in std_logic_vector(STATUS_KIND_WIDTH-1 downto 0);
        -- *FEEDBACK SUBSCRIBER*
        f_start_dds                 : out std_logic;
        f_ack_dds                   : in std_logic;
        f_opcode_dds                : out DDS_READER_OPCODE_TYPE;
        f_instance_state_dds        : out std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0);
        f_view_state_dds            : out std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0);
        f_sample_state_dds          : out std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0);
        f_instance_handle_dds       : out INSTANCE_HANDLE_TYPE;
        f_max_samples_dds           : out std_logic_vector(MAX_SAMPLES_WIDTH-1 downto 0);
        f_get_data_dds              : out std_logic;
        f_done_dds                  : in std_logic;
        f_return_code_dds           : in std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
        f_valid_in_dds              : in std_logic;
        f_ready_in_dds              : out std_logic;
        f_data_in_dds               : in std_logic_vector(WORD_WIDTH-1 downto 0);
        f_last_word_in_dds          : in std_logic;
        f_sample_info_dds           : in SAMPLE_INFO_TYPE;
        f_sample_info_valid_dds     : in std_logic;
        f_sample_info_ack_dds       : out std_logic;
        f_eoc_dds                   : in std_logic;
        f_status_dds                : in std_logic_vector(STATUS_KIND_WIDTH-1 downto 0);
        
        -- *USER*
        start                       : in std_logic;
        opcode                      : in ROS_ACTION_OPCODE_TYPE;
        ack                         : out std_logic;
        sequence_id                 : out std_logic_vector(ROS_SEQUENCE_ID_WIDTH-1 downto 0);
        service_info                : out SERVICE_INFO_TYPE;
        data_available_g            : out std_logic;
        data_available_r            : out std_logic;
        data_available_c            : out std_logic;
        data_available_f            : out std_logic;
        done                        : out std_logic;
        return_code                 : out std_logic_vector(ROS_RETCODE_WIDTH-1 downto 0);
        -- GOAL SIGNALS
        goal_id                     : in std_logic_vector(UUID_WIDTH-1 downto 0);
        -- ###GENERATED START###
        goal_order                  : in std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
        -- ###GENERATED END###
        goal_accepted               : out std_logic;
        goal_stamp                  : out ROS_TIME_TYPE;
        -- RESULT SIGNALS
        result_goal_id              : in std_logic_vector(UUID_WIDTH-1 downto 0);
        result_status               : out std_logic_vector(CDR_INT8_WIDTH-1 downto 0);
        -- ###GENERATED START###
        result_seq_len              : out std_logic_vector(R_RR_SEQ_ADDR_WIDTH-1 downto 0);
        result_seq_addr             : in std_logic_vector(R_RR_SEQ_ADDR_WIDTH-1 downto 0);
        result_seq_ready            : out std_logic;
        result_seq_ren              : in std_logic;
        result_seq_valid            : out std_logic;
        result_seq_ack              : in std_logic;
        result_seq                  : out std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
        -- ###GENERATED END###
        -- CANCEL
        cancel_goal_id                  : in std_logic_vector(UUID_WIDTH-1 downto 0);
        cancel_stamp                    : in ROS_TIME_TYPE;
        cancel_return_code              : out std_logic_vector(CDR_INT8_WIDTH-1 downto 0);
        cancel_goals_canceling_len      : out std_logic_vector(CancelGoal_package.RR_GOALS_CANCELING_ADDR_WIDTH-1 downto 0);
        cancel_goals_canceling_addr     : in std_logic_vector(CancelGoal_package.RR_GOALS_CANCELING_ADDR_WIDTH-1 downto 0);
        cancel_goals_canceling_ready    : out std_logic;
        cancel_goals_canceling_ren      : in std_logic;
        cancel_goals_canceling_valid    : out std_logic;
        cancel_goals_canceling_ack      : in std_logic;
        cancel_goals_canceling_goal_id  : out std_logic_vector(UUID_WIDTH-1 downto 0);
        cancel_goals_canceling_stamp    : out std_logic_vector(ROS_TIME_WIDTH-1 downto 0);
        -- FEEDBACK SIGNALS
        feedback_goal_id            : out std_logic_vector(UUID_WIDTH-1 downto 0);
        -- ###GENERATED START###
        feedback_seq_len                : out std_logic_vector(F_SEQ_ADDR_WIDTH-1 downto 0);
        feedback_seq_addr               : in std_logic_vector(F_SEQ_ADDR_WIDTH-1 downto 0);
        feedback_seq_ready              : out std_logic;
        feedback_seq_ren                : in std_logic;
        feedback_seq_valid              : out std_logic;
        feedback_seq_ack                : in std_logic;
        feedback_seq                    : out std_logic_vector(CDR_LONG_WIDTH-1 downto 0)
        -- ###GENERATED END###
    );
end entity;

architecture arch of Fibonacci_ros_action_client is
    
    --*****TYPE DECLARATION*****
    type STAGE_TYPE is (IDLE,SEND_GOAL_REQUEST,TAKE_GOAL_RESPONSE,SEND_RESULT_REQUEST,TAKE_RESULT_RESPONSE,SEND_CANCEL_REQUEST,TAKE_CANCEL_RESPONSE,TAKE_FEEDBACK,RETURN_ROS);
    
    --*****SIGNAL DECLARATION*****
    signal stage, stage_next : STAGE_TYPE;
    signal cnt, cnt_next : natural range 0 to 5;
    signal g_start_user, r_start_user, c_start_user, g_ack_user, r_ack_user, c_ack_user, g_taken_user, r_taken_user, c_taken_user, g_done_user, r_done_user, c_done_user : std_logic;
    signal g_opcode_user, r_opcode_user, c_opcode_user : ROS_SERVICE_OPCODE_TYPE;
    signal g_service_info_user, r_service_info_user, c_service_info_user : SERVICE_INFO_TYPE;
    signal g_sequence_id_user, r_sequence_id_user, c_sequence_id_user : std_logic_vector(ROS_SEQUENCE_ID_WIDTH-1 downto 0);
    signal g_return_code_user, r_return_code_user, c_return_code_user : std_logic_vector(ROS_RETCODE_WIDTH-1 downto 0);
    
    signal f_start_user, f_ack_user, f_done_user, f_taken_user : std_logic;
    signal f_opcode_user : ROS_TOPIC_OPCODE_TYPE;
    signal f_return_code_user : std_logic_vector(ROS_RETCODE_WIDTH-1 downto 0);
    signal f_message_info_user : MESSAGE_INFO_TYPE;
    
    signal return_code_latch, return_code_latch_next : std_logic_vector(ROS_RETCODE_WIDTH-1 downto 0);
    
    signal goal_stamp_sig : std_logic_vector(ROS_TIME_WIDTH-1 downto 0);
    
begin
    
    goal_srv_client_inst : entity work.Fibonacci_ros_action_goal_srv_client(arch)
        generic map (
            LITTLE_ENDIAN   => LITTLE_ENDIAN
        )
        port map (
            clk                     => clk,
            reset                   => reset,
            start_r                 => g_start_r,
            ack_r                   => g_ack_r,
            opcode_r                => g_opcode_r,
            instance_state_r        => g_instance_state_r,
            view_state_r            => g_view_state_r,
            sample_state_r          => g_sample_state_r,
            instance_handle_r       => g_instance_handle_r,
            max_samples_r           => g_max_samples_r,
            get_data_r              => g_get_data_r,
            done_r                  => g_done_r,
            return_code_r           => g_return_code_r,
            valid_in_r              => g_valid_in_r,
            ready_in_r              => g_ready_in_r,
            data_in_r               => g_data_in_r,
            last_word_in_r          => g_last_word_in_r,
            sample_info_r           => g_sample_info_r,
            sample_info_valid_r     => g_sample_info_valid_r,
            sample_info_ack_r       => g_sample_info_ack_r,
            eoc_r                   => g_eoc_r,
            status_r                => g_status_r,
            start_w                 => g_start_w,
            ack_w                   => g_ack_w,
            opcode_w                => g_opcode_w,
            instance_handle_out_w   => g_instance_handle_out_w,
            source_ts_w             => g_source_ts_w,
            max_wait_w              => g_max_wait_w,
            done_w                  => g_done_w,
            return_code_w           => g_return_code_w,
            instance_handle_in_w    => g_instance_handle_in_w,
            valid_out_w             => g_valid_out_w,
            ready_out_w             => g_ready_out_w,
            data_out_w              => g_data_out_w,
            last_word_out_w         => g_last_word_out_w,
            valid_in_w              => g_valid_in_w,
            ready_in_w              => g_ready_in_w,
            data_in_w               => g_data_in_w,
            last_word_in_w          => g_last_word_in_w,
            status_w                => g_status_w,
            start_user              => g_start_user,
            ack_user                => g_ack_user,
            opcode_user             => g_opcode_user,
            done_user               => g_done_user,
            return_code_user        => g_return_code_user,
            service_info_user       => g_service_info_user,
            sequence_id_user        => g_sequence_id_user,
            data_available_user     => data_available_g,
            taken_user              => g_taken_user,
            goal_id                 => goal_id,
            -- ###GENERATED START###
            order                   => goal_order,
            -- ###GENERATED END###
            accepted                => goal_accepted,
            stamp                   => goal_stamp_sig
        );
    
    goal_stamp  <= to_ROS_TIME(goal_stamp_sig);
    
    result_srv_client_inst : entity work.Fibonacci_ros_action_result_srv_client(arch)
        generic map (
            LITTLE_ENDIAN   => LITTLE_ENDIAN
        )
        port map (
            clk                     => clk,
            reset                   => reset,
            start_r                 => r_start_r,
            ack_r                   => r_ack_r,
            opcode_r                => r_opcode_r,
            instance_state_r        => r_instance_state_r,
            view_state_r            => r_view_state_r,
            sample_state_r          => r_sample_state_r,
            instance_handle_r       => r_instance_handle_r,
            max_samples_r           => r_max_samples_r,
            get_data_r              => r_get_data_r,
            done_r                  => r_done_r,
            return_code_r           => r_return_code_r,
            valid_in_r              => r_valid_in_r,
            ready_in_r              => r_ready_in_r,
            data_in_r               => r_data_in_r,
            last_word_in_r          => r_last_word_in_r,
            sample_info_r           => r_sample_info_r,
            sample_info_valid_r     => r_sample_info_valid_r,
            sample_info_ack_r       => r_sample_info_ack_r,
            eoc_r                   => r_eoc_r,
            status_r                => r_status_r,
            start_w                 => r_start_w,
            ack_w                   => r_ack_w,
            opcode_w                => r_opcode_w,
            instance_handle_out_w   => r_instance_handle_out_w,
            source_ts_w             => r_source_ts_w,
            max_wait_w              => r_max_wait_w,
            done_w                  => r_done_w,
            return_code_w           => r_return_code_w,
            instance_handle_in_w    => r_instance_handle_in_w,
            valid_out_w             => r_valid_out_w,
            ready_out_w             => r_ready_out_w,
            data_out_w              => r_data_out_w,
            last_word_out_w         => r_last_word_out_w,
            valid_in_w              => r_valid_in_w,
            ready_in_w              => r_ready_in_w,
            data_in_w               => r_data_in_w,
            last_word_in_w          => r_last_word_in_w,
            status_w                => r_status_w,
            start_user              => r_start_user,
            ack_user                => r_ack_user,
            opcode_user             => r_opcode_user,
            done_user               => r_done_user,
            return_code_user        => r_return_code_user,
            service_info_user       => r_service_info_user,
            sequence_id_user        => r_sequence_id_user,
            data_available_user     => data_available_r,
            taken_user              => r_taken_user,
            goal_id                 => result_goal_id,
            status                  => result_status,
            -- ###GENERATED START###
            seq_len                 => result_seq_len,
            seq_addr                => result_seq_addr,
            seq_ready               => result_seq_ready,
            seq_ren                 => result_seq_ren,
            seq_valid               => result_seq_valid,
            seq_ack                 => result_seq_ack,
            seq                     => result_seq
            -- ###GENERATED END###
        );
        
    cancel_srv_client_inst : entity work.CancelGoal_ros_srv_client(arch)
        generic map (
            LITTLE_ENDIAN   => LITTLE_ENDIAN
        )
        port map (
            clk                         => clk,
            reset                       => reset,
            start_r                     => c_start_r,
            ack_r                       => c_ack_r,
            opcode_r                    => c_opcode_r,
            instance_state_r            => c_instance_state_r,
            view_state_r                => c_view_state_r,
            sample_state_r              => c_sample_state_r,
            instance_handle_r           => c_instance_handle_r,
            max_samples_r               => c_max_samples_r,
            get_data_r                  => c_get_data_r,
            done_r                      => c_done_r,
            return_code_r               => c_return_code_r,
            valid_in_r                  => c_valid_in_r,
            ready_in_r                  => c_ready_in_r,
            data_in_r                   => c_data_in_r,
            last_word_in_r              => c_last_word_in_r,
            sample_info_r               => c_sample_info_r,
            sample_info_valid_r         => c_sample_info_valid_r,
            sample_info_ack_r           => c_sample_info_ack_r,
            eoc_r                       => c_eoc_r,
            status_r                    => c_status_r,
            start_w                     => c_start_w,
            ack_w                       => c_ack_w,
            opcode_w                    => c_opcode_w,
            instance_handle_out_w       => c_instance_handle_out_w,
            source_ts_w                 => c_source_ts_w,
            max_wait_w                  => c_max_wait_w,
            done_w                      => c_done_w,
            return_code_w               => c_return_code_w,
            instance_handle_in_w        => c_instance_handle_in_w,
            valid_out_w                 => c_valid_out_w,
            ready_out_w                 => c_ready_out_w,
            data_out_w                  => c_data_out_w,
            last_word_out_w             => c_last_word_out_w,
            valid_in_w                  => c_valid_in_w,
            ready_in_w                  => c_ready_in_w,
            data_in_w                   => c_data_in_w,
            last_word_in_w              => c_last_word_in_w,
            status_w                    => c_status_w,
            start_user                  => c_start_user,
            ack_user                    => c_ack_user,
            opcode_user                 => c_opcode_user,
            done_user                   => c_done_user,
            return_code_user            => c_return_code_user,
            service_info_user           => c_service_info_user,
            sequence_id_user            => c_sequence_id_user,
            data_available_user         => data_available_c,
            taken_user                  => c_taken_user,
            goal_info_goal_id           => cancel_goal_id,
            goal_info_stamp             => std_logic_vector(to_unsigned(cancel_stamp)),
            return_code                 => cancel_return_code,
            goals_canceling_len         => cancel_goals_canceling_len,
            goals_canceling_addr        => cancel_goals_canceling_addr,
            goals_canceling_ready       => cancel_goals_canceling_ready,
            goals_canceling_ren         => cancel_goals_canceling_ren,
            goals_canceling_valid       => cancel_goals_canceling_valid,
            goals_canceling_ack         => cancel_goals_canceling_ack,
            goals_canceling_goal_id     => cancel_goals_canceling_goal_id,
            goals_canceling_stamp       => cancel_goals_canceling_stamp
        );
    
    feedback_gen : if ENABLE_FEEDBACK = '1' generate
        feedback_sub_inst : entity work.Fibonacci_ros_action_feedback_sub(arch)
            port map (
                clk                     => clk,
                reset                   => reset,
                start_dds               => f_start_dds,
                ack_dds                 => f_ack_dds,
                opcode_dds              => f_opcode_dds,
                instance_state_dds      => f_instance_state_dds,
                view_state_dds          => f_view_state_dds,
                sample_state_dds        => f_sample_state_dds,
                instance_handle_dds     => f_instance_handle_dds,
                max_samples_dds         => f_max_samples_dds,
                get_data_dds            => f_get_data_dds,
                done_dds                => f_done_dds,
                return_code_dds         => f_return_code_dds,
                valid_in_dds            => f_valid_in_dds,
                ready_in_dds            => f_ready_in_dds,
                data_in_dds             => f_data_in_dds,
                last_word_in_dds        => f_last_word_in_dds,
                sample_info_dds         => f_sample_info_dds,
                sample_info_valid_dds   => f_sample_info_valid_dds,
                sample_info_ack_dds     => f_sample_info_ack_dds,
                eoc_dds                 => f_eoc_dds,
                status_dds              => f_status_dds,
                start_user              => f_start_user,
                opcode_user             => f_opcode_user,
                ack_user                => f_ack_user,
                done_user               => f_done_user,
                return_code_user        => f_return_code_user,
                message_info_user       => f_message_info_user,
                taken_user              => f_taken_user,
                data_available_user     => data_available_f,
                -- ###GENERATED START###
                goal_id                 => feedback_goal_id,
                seq_len                 => feedback_seq_len,
                seq_addr                => feedback_seq_addr,
                seq_ready               => feedback_seq_ready,
                seq_ren                 => feedback_seq_ren,
                seq_valid               => feedback_seq_valid,
                seq_ack                 => feedback_seq_ack,
                seq                     => feedback_seq
                -- ###GENERATED END###
            );
    else generate
        f_start_dds             <= '0';
        f_opcode_dds            <= NOP;
        f_instance_state_dds    <= ANY_INSTANCE_STATE;
        f_view_state_dds        <= ANY_VIEW_STATE;
        f_sample_state_dds      <= ANY_SAMPLE_STATE;
        f_instance_handle_dds   <= HANDLE_NIL;
        f_max_samples_dds       <= (others => '0');
        f_get_data_dds          <= '0';
        f_ready_in_dds          <= '0';
        f_sample_info_ack_dds   <= '0';
        f_ack_user              <= '0';
        f_done_user             <= '0';
        f_return_code_user      <= ROS_RET_OK;
        data_available_f        <= '0';
        f_message_info_user     <= EMPTY_MESSAGE_INFO;
        f_taken_user            <= '0';
        feedback_goal_id        <= (others => '0');
        -- ###GENERATED START###
        feedback_seq_len        <= (others => '0');
        feedback_seq_ready      <= '0';
        feedback_seq_valid      <= '0';
        feedback_seq            <= (others => '0');
        -- ###GENERATED END###
    end generate;
    
    
    main_prc : process(all)
    begin
        -- DEFAULT
        stage_next              <= stage;
        cnt_next                <= cnt;
        return_code_latch_next  <= return_code_latch;
        -- DEFAULT Unregistered
        f_start_user        <= '0';
        f_opcode_user       <= NOP;
        g_start_user        <= '0';
        r_opcode_user       <= NOP;
        r_start_user        <= '0';
        g_opcode_user       <= NOP;
        c_start_user        <= '0';
        c_opcode_user       <= NOP;
        sequence_id         <= (others => '0');
        service_info        <= EMPTY_SERVICE_INFO;
        ack                 <= '0';
        done                <= '0';
        return_code         <= ROS_RET_OK;
        
        case (stage) is
            when IDLE =>
                if (start = '1') then
                    ack <= '1';
                    case (opcode) is
                        when SEND_GOAL_REQUEST =>
                            stage_next  <= SEND_GOAL_REQUEST;
                            cnt_next    <= 0;
                        when TAKE_GOAL_RESPONSE =>
                            stage_next  <= TAKE_GOAL_RESPONSE;
                            cnt_next    <= 0;
                        when SEND_RESULT_REQUEST =>
                            stage_next  <= SEND_RESULT_REQUEST;
                            cnt_next    <= 0;
                        when TAKE_RESULT_RESPONSE =>
                            stage_next  <= TAKE_RESULT_RESPONSE;
                            cnt_next    <= 0;
                        when SEND_CANCEL_REQUEST =>
                            stage_next  <= SEND_CANCEL_REQUEST;
                            cnt_next    <= 0;
                        when TAKE_CANCEL_RESPONSE =>
                            stage_next  <= TAKE_CANCEL_RESPONSE;
                            cnt_next    <= 0;
                        when TAKE_FEEDBACK =>
                            -- SYNTHESIS GUARD
                            if (ENABLE_FEEDBACK = '1') then
                                stage_next  <= TAKE_FEEDBACK;
                                cnt_next    <= 0;
                            else
                                return_code_latch_next  <= ROS_RET_UNSUPPORTED;
                                stage_next              <= RETURN_ROS;
                            end if;
                        when others =>
                            return_code_latch_next  <= ROS_RET_UNSUPPORTED;
                            stage_next              <= RETURN_ROS;
                    end case;
                end if;
            when SEND_GOAL_REQUEST =>
                case (cnt) is
                    -- Take
                    when 0 =>
                        g_start_user        <= '1';
                        g_opcode_user       <= SEND_REQUEST;
                        
                        if (g_ack_user = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- Wait for Subscriber
                    when 1 =>
                        sequence_id     <= g_sequence_id_user;
                        done            <= g_done_user;
                        return_code     <= g_return_code_user;
                        
                        if (g_done_user = '1') then
                            -- DONE
                            stage_next  <= IDLE;
                        end if;
                    when others =>
                        null;
                end case;
            when TAKE_GOAL_RESPONSE =>
                case (cnt) is
                    -- Take
                    when 0 =>
                        g_start_user        <= '1';
                        g_opcode_user       <= TAKE_RESPONSE;
                        
                        if (g_ack_user = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- Wait for Subscriber
                    when 1 =>
                        service_info    <= g_service_info_user;
                        return_code     <= g_return_code_user;
                        
                        if (g_done_user = '1') then
                            if (g_taken_user = '1') then
                                done        <= g_done_user;
                                stage_next  <= IDLE;
                            else
                                return_code_latch_next  <= ROS_RET_ACTION_CLIENT_TAKE_FAILED;
                                stage_next              <= RETURN_ROS;
                            end if;
                        end if;
                    when others =>
                        null;
                end case;
            when SEND_RESULT_REQUEST =>
                case (cnt) is
                    -- Take
                    when 0 =>
                        r_start_user        <= '1';
                        r_opcode_user       <= SEND_REQUEST;
                        
                        if (r_ack_user = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- Wait for Subscriber
                    when 1 =>
                        sequence_id <= r_sequence_id_user;
                        done        <= r_done_user;
                        return_code <= r_return_code_user;
                        
                        if (r_done_user = '1') then
                            -- DONE
                            stage_next  <= IDLE;
                        end if;
                    when others =>
                        null;
                end case;
            when TAKE_RESULT_RESPONSE =>
                case (cnt) is
                    -- Take
                    when 0 =>
                        r_start_user        <= '1';
                        r_opcode_user       <= TAKE_RESPONSE;
                        
                        if (r_ack_user = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- Wait for Subscriber
                    when 1 =>
                        service_info    <= r_service_info_user;
                        return_code     <= r_return_code_user;
                        
                        if (r_done_user = '1') then
                            if (r_taken_user = '1') then
                                done        <= r_done_user;
                                stage_next  <= IDLE;
                            else
                                return_code_latch_next  <= ROS_RET_ACTION_CLIENT_TAKE_FAILED;
                                stage_next              <= RETURN_ROS;
                            end if;
                        end if;
                    when others =>
                        null;
                end case;
            when SEND_CANCEL_REQUEST =>
                case (cnt) is
                    -- Take
                    when 0 =>
                        c_start_user        <= '1';
                        c_opcode_user       <= SEND_REQUEST;
                        
                        if (c_ack_user = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- Wait for Subscriber
                    when 1 =>
                        sequence_id <= c_sequence_id_user;
                        done        <= c_done_user;
                        return_code <= c_return_code_user;
                        
                        if (c_done_user = '1') then
                            -- DONE
                            stage_next  <= IDLE;
                        end if;
                    when others =>
                        null;
                end case;
            when TAKE_CANCEL_RESPONSE =>
                case (cnt) is
                    -- Take
                    when 0 =>
                        c_start_user        <= '1';
                        c_opcode_user       <= TAKE_RESPONSE;
                        
                        if (c_ack_user = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- Wait for Subscriber
                    when 1 =>
                        service_info    <= c_service_info_user;
                        return_code     <= c_return_code_user;
                        
                        if (c_done_user = '1') then
                            if (c_taken_user = '1') then
                                done        <= c_done_user;
                                stage_next  <= IDLE;
                            else
                                return_code_latch_next  <= ROS_RET_ACTION_CLIENT_TAKE_FAILED;
                                stage_next              <= RETURN_ROS;
                            end if;
                        end if;
                    when others =>
                        null;
                end case;
            when TAKE_FEEDBACK =>
                case (cnt) is
                    -- Take
                    when 0 =>
                        f_start_user    <= '1';
                        f_opcode_user   <= TAKE;
                        
                        if (f_ack_user = '1') then
                            cnt_next    <= cnt + 1;
                        end if;
                    -- Wait for Subscriber
                    when 1 =>
                        if (f_done_user = '1') then
                            return_code <= f_return_code_user;
                            
                            if (f_taken_user = '1') then
                                done    <= f_done_user;
                                -- DONE
                                stage_next  <= IDLE;
                            else
                                return_code_latch_next  <= ROS_RET_ACTION_CLIENT_TAKE_FAILED;
                                stage_next              <= RETURN_ROS;
                            end if;
                        end if;
                    when others =>
                        null;
                end case;
            when RETURN_ROS =>
                done        <= '1';
                return_code <= return_code_latch;
                -- DONE
                stage_next  <= IDLE;
        end case;
    end process;
    
    sync_prc : process(clk)
    begin
        if rising_edge(clk) then
            if (reset = '1') then
                stage               <= IDLE;
                cnt                 <= 0;
                return_code_latch   <= ROS_RET_OK;
            else
                stage               <= stage_next;
                cnt                 <= cnt_next;
                return_code_latch   <= return_code_latch_next;
            end if;
        end if;
    end process;
    
end architecture;
