LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.NUMERIC_STD.ALL;

ENTITY DC_Motor_Control_Top IS
    PORT (
        -- 时钟和复位
        CLK_MAIN    : IN STD_LOGIC;   -- 主时钟 (例如 50MHz)
        RST         : IN STD_LOGIC;   -- 全局复位，高电平有效
        
        -- ADC 接口 (用于速度反馈或电位器输入)
        ADC_DATA    : IN STD_LOGIC_VECTOR(7 DOWNTO 0); -- ADC 数据输入
        ADC_EOC     : IN STD_LOGIC;   -- ADC 转换结束信号
        ADC_ALE     : OUT STD_LOGIC;
        ADC_START   : OUT STD_LOGIC;
        ADC_OE      : OUT STD_LOGIC;
        ADC_ADDA    : OUT STD_LOGIC;  -- 通常置'0'，选择通道
        
        -- 控制信号输入
        SPEED_SW    : IN STD_LOGIC_VECTOR(3 DOWNTO 0); -- 速度档位选择
        DIR_SW      : IN STD_LOGIC;   -- 方向控制: '0'=正转, '1'=反转
        S           : IN STD_LOGIC;   -- 用于PW模块的旋转方向控制（可选）
        
        -- 电机驱动输出
        PWM_OUT     : OUT STD_LOGIC;   -- PWM 信号
        DIR_OUT_A   : OUT STD_LOGIC;   -- H桥方向控制A
        DIR_OUT_B   : OUT STD_LOGIC;   -- H桥方向控制B (通常与A反相)
        
        -- 数码管显示
        SEG_DATA    : OUT STD_LOGIC_VECTOR(6 DOWNTO 0); -- 七段数码管数据
        SEG_SEL     : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)  -- 数码管位选（例如显示占空比或速度）
        -- 可根据实际硬件扩展更多位选
    );
END ENTITY DC_Motor_Control_Top;

ARCHITECTURE Structural OF DC_Motor_Control_Top IS

    -- 组件声明
    COMPONENT ADCINT IS
        PORT ( 
            D       : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
            CLK     : IN STD_LOGIC;
            EOC     : IN STD_LOGIC;
            RST     : IN STD_LOGIC;
            ALE     : OUT STD_LOGIC;
            START   : OUT STD_LOGIC;
            OE      : OUT STD_LOGIC;
            ADDA    : OUT STD_LOGIC;
            Q       : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
        );
    END COMPONENT;
    
    COMPONENT PW IS
        PORT (
            CLK : IN STD_LOGIC;
            S   : IN STD_LOGIC;
            Q   : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
        );
    END COMPONENT;
    
    COMPONENT SQU IS
        PORT (
            CIN : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
            ADR : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
            OT  : OUT STD_LOGIC
        );
    END COMPONENT;
    
    COMPONENT DECL7S IS
        PORT (
            A       : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
            LED7S   : OUT STD_LOGIC_VECTOR(6 DOWNTO 0)
        );
    END COMPONENT;
    
    COMPONENT CNT4B IS
        PORT (
            CLK     : IN STD_LOGIC;
            DOUT    : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
        );
    END COMPONENT;
    
    COMPONENT CNT8B IS
        PORT (
            CLK     : IN STD_LOGIC;
            DOUT    : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
        );
    END COMPONENT;
    
    COMPONENT MUX IS
        PORT (
            SL      : IN STD_LOGIC;
            M1      : IN STD_LOGIC;
            QQ      : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
            QOUT    : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
            MM0     : OUT STD_LOGIC;
            MM1     : OUT STD_LOGIC
        );
    END COMPONENT;
    
    COMPONENT MUX41 IS
        PORT (
            F1      : IN STD_LOGIC;
            F2      : IN STD_LOGIC;
            F3      : IN STD_LOGIC;
            F4      : IN STD_LOGIC;
            DIN     : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
            FOT     : OUT STD_LOGIC
        );
    END COMPONENT;
    
    COMPONENT SLT IS
        PORT (
            SL      : IN STD_LOGIC;
            M       : IN STD_LOGIC;
            M0      : OUT STD_LOGIC;
            M1      : OUT STD_LOGIC
        );
    END COMPONENT;

    -- 内部信号定义
    SIGNAL clk_div          : STD_LOGIC; -- 分频后时钟
    SIGNAL pwm_compare      : STD_LOGIC_VECTOR(7 DOWNTO 0); -- PWM比较值（占空比）
    SIGNAL pwm_counter      : STD_LOGIC_VECTOR(7 DOWNTO 0); -- PWM计数器
    SIGNAL adc_result       : STD_LOGIC_VECTOR(7 DOWNTO 0); -- ADC转换结果
    SIGNAL duty_cycle       : STD_LOGIC_VECTOR(7 DOWNTO 0); -- 计算出的占空比
    SIGNAL seg_data_in      : STD_LOGIC_VECTOR(3 DOWNTO 0); -- 数码管输入数据
    SIGNAL seg_sel_counter  : STD_LOGIC_VECTOR(1 DOWNTO 0); -- 数码管位选计数器
    SIGNAL dir_internal     : STD_LOGIC; -- 内部方向信号

BEGIN

    -- 时钟分频进程：生成较低频率的时钟用于PWM等
    PROCESS (CLK_MAIN, RST)
        VARIABLE counter : INTEGER RANGE 0 TO 1000;
    BEGIN
        IF RST = '1' THEN
            counter := 0;
            clk_div <= '0';
        ELSIF RISING_EDGE(CLK_MAIN) THEN
            IF counter >= 500 THEN -- 分频系数，根据实际PWM频率需求调整
                counter := 0;
                clk_div <= NOT clk_div;
            ELSE
                counter := counter + 1;
            END IF;
        END IF;
    END PROCESS;

    -- ADC接口实例化，用于读取速度反馈或电位器电压
    U_ADC : ADCINT
    PORT MAP (
        D       => ADC_DATA,
        CLK     => clk_div,      -- 使用分频后时钟
        EOC     => ADC_EOC,
        RST     => RST,
        ALE     => ADC_ALE,
        START   => ADC_START,
        OE      => ADC_OE,
        ADDA    => ADC_ADDA,     -- 通常选择通道0
        Q       => adc_result    -- 转换结果
    );

    -- 8位计数器实例化，作为PWM计数器和地址发生器
    U_CNT8B : CNT8B
    PORT MAP (
        CLK     => clk_div,
        DOUT    => pwm_counter
    );

    -- PWM比较器实例化：当计数值小于比较值时输出高电平
    U_SQU : SQU
    PORT MAP (
        CIN     => duty_cycle,   -- 占空比设定值
        ADR     => pwm_counter,  -- PWM计数器值
        OT      => PWM_OUT       -- PWM输出
    );

    -- 方向控制逻辑
    dir_internal <= DIR_SW; -- 可以直接用开关控制，或根据ADC结果等复杂逻辑控制
    
    -- H桥方向控制：防止直通，通常互补
    DIR_OUT_A <= dir_internal;
    DIR_OUT_B <= NOT dir_internal;

    -- 占空比设置进程：根据速度档位或ADC反馈设置PWM占空比
    PROCESS (SPEED_SW, adc_result, RST)
    BEGIN
        IF RST = '1' THEN
            duty_cycle <= (OTHERS => '0');
        ELSE
            -- 示例：速度档位直接映射到不同占空比
            CASE SPEED_SW IS
                WHEN "0000" => duty_cycle <= "00000000"; -- 停止
                WHEN "0001" => duty_cycle <= "00011111"; -- 低速 ~12.5%
                WHEN "0010" => duty_cycle <= "00111111"; -- 中低速 ~25%
                WHEN "0011" => duty_cycle <= "01011111"; -- 中速 ~37.5%
                WHEN "0100" => duty_cycle <= "01111111"; -- 中高速 ~50%
                WHEN "0101" => duty_cycle <= "10011111"; -- 高速 ~62.5%
                WHEN "0110" => duty_cycle <= "10111111"; -- 超高速 ~75%
                WHEN "0111" => duty_cycle <= "11011111"; -- 更高 ~87.5%
                WHEN OTHERS => duty_cycle <= "11111111"; -- 全速 ~100%
            END CASE;
            
            -- 闭环控制示例：根据ADC反馈（如电位器或转速传感器）调整占空比
            -- duty_cycle <= adc_result; -- 简单直接映射
        END IF;
    END PROCESS;

    -- 数码管显示控制：显示当前占空比或速度档位
    U_CNT4B : CNT4B -- 生成数码管位选信号
    PORT MAP (
        CLK     => CLK_MAIN, -- 使用高速时钟扫描
        DOUT    => seg_sel_counter
    );
    
    -- 数码管解码器实例化
    U_DECL7S : DECL7S
    PORT MAP (
        A       => duty_cycle(7 DOWNTO 4), -- 显示占空比高4位（0-15）
        LED7S   => SEG_DATA
    );
    
    -- 数码管位选控制（示例为4位数码管中的1位）
    PROCESS (seg_sel_counter)
    BEGIN
        CASE seg_sel_counter IS
            WHEN "00" => SEG_SEL <= "1110"; -- 选中第一位
            -- WHEN "01" => SEG_SEL <= "1101"; -- 选中第二位（如需多位显示）
            -- WHEN "10" => SEG_SEL <= "1011"; -- 选中第三位
            -- WHEN "11" => SEG_SEL <= "0111"; -- 选中第四位
            WHEN OTHERS => SEG_SEL <= "1111"; -- 全部关闭
        END CASE;
    END PROCESS;

END ARCHITECTURE Structural;
