本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:本文将详细介绍如何使用Altera公司的Quartus II 6.0软件,结合VHDL或Verilog硬件描述语言,设计一个高效的十字交叉路口三色交通灯控制系统。文章将指导读者了解整个设计流程,包括创建项目、编写HDL代码、编译与仿真、布局与布线,直至下载测试和调试优化。掌握这一课程设计,不仅可以学习到数字逻辑设计的基础知识,而且能深入理解状态机、定时器、输入输出接口等核心概念。
Quartus II

1. Quartus II 6.0软件介绍

Quartus II 6.0是Altera公司开发的一款集成的FPGA设计软件,提供了从设计输入到芯片配置的完整流程。它广泛应用于FPGA、CPLD以及ASIC设计,因其高效的设计流程、丰富的资源库和用户友好的界面而闻名。

Quartus II 6.0的基本功能与界面布局

Quartus II 6.0的基本功能包括设计输入、综合、仿真、编译和配置。界面布局分为项目导航器、设计编辑器、分析与综合工具、仿真工具等多个部分,用户可以根据项目需求快速定位到相应的功能模块。

Quartus II 6.0在FPGA开发中的作用和地位

在FPGA开发中,Quartus II 6.0不仅是设计工具,更是开发者与硬件沟通的桥梁。它具备高度的集成度和兼容性,支持多种FPGA芯片,是众多电子工程师和科研人员的首选开发环境。通过本章的学习,读者将对Quartus II 6.0有一个初步的理解,为后续深入学习FPGA开发奠定基础。

2. FPGA开发环境构建

2.1 Quartus II 6.0开发环境的搭建

2.1.1 安装与配置流程

Quartus II 是一款功能强大的FPGA和CPLD设计软件,由Altera公司开发,现为Intel旗下产品。Quartus II 6.0为FPGA开发提供了集成的设计环境,支持逻辑设计、仿真、编译、下载等全周期工作。在搭建Quartus II 6.0开发环境之前,请确保您的计算机满足最低配置要求。

安装Quartus II 需要遵循以下步骤:

  1. 下载Quartus II 6.0安装包。
  2. 运行安装程序并选择“Standard”安装类型。
  3. 选择安装路径并遵守许可协议。
  4. 确认安装信息无误后点击“Install”开始安装过程。
  5. 安装完成后,重启计算机。

在安装过程中,需要特别注意的是,选择安装的组件应该根据个人的项目需求进行挑选,避免不必要的冗余安装,提高安装效率。

2.1.2 开发环境初始化设置

初始化设置对于一个高效的开发环境至关重要。Quartus II 6.0提供了灵活的环境设置选项,能够帮助开发者提升开发效率。

  1. 打开Quartus II 6.0软件,选择“Tools”菜单下的“Options”进行环境设置。
  2. 在“General”选项卡下,可以设置项目文件夹的默认路径,以及Quartus II软件的界面语言。
  3. 在“Device”选项卡中,选择您将要使用的FPGA芯片型号,这对于编译和仿真过程中的芯片特性适配至关重要。
  4. 在“EDA Tool”选项卡中,配置仿真工具和其他设计辅助工具的路径。
  5. 在“Text Editor”选项卡中,您可以设置用于编写设计代码的文本编辑器。

初始化设置的目的是为了让Quartus II软件与您的开发习惯以及硬件设备相匹配,从而优化工作流和提高工作效率。

2.2 FPGA开发的硬件要求

2.2.1 FPGA开发板的选择标准

选择合适的FPGA开发板是进行FPGA项目开发的先决条件。一个好的开发板应满足以下几点:

  1. 芯片类型 :确保开发板上搭载的FPGA芯片与您的项目需求相匹配,包括逻辑单元数量、内存容量、IO引脚数量、高速收发器等资源。
  2. 扩展性 :考察开发板上是否提供足够的扩展接口,如PCIe、USB、以太网等,以便将来可能的项目扩展。
  3. 文档与支持 :检查开发板厂商是否提供详细的文档和开发者社区支持,这将在遇到问题时提供帮助。
  4. 成本效益 :评估开发板的成本与项目预算,性价比是不可忽视的因素。

选择FPGA开发板时,需仔细考量上述标准,以便为后续的项目开发奠定坚实的硬件基础。

2.2.2 硬件连接与测试基础

在FPGA开发板选定并收到后,接下来的步骤是硬件连接和基础测试。

  1. 硬件连接 :按照开发板的使用手册连接电源、下载电缆以及其它可能需要的外围设备。
  2. 供电测试 :在连接电源之前,检查所有硬件连接是否正确无误,并确保没有短路的风险。给开发板供电后,检查电源指示灯是否正常亮起。
  3. 板载功能测试 :使用开发板自带的简单示例设计进行板载LED、按钮等基本功能的测试,验证硬件的完好性。

完成硬件连接和测试后,您就可以开始FPGA开发之旅了。

2.3 Quartus II 6.0的项目管理

2.3.1 项目创建与文件结构

Quartus II 6.0项目管理是提高设计效率的关键。在创建项目时,需要遵循以下步骤:

  1. 打开Quartus II软件,点击“File”菜单下的“New Project Wizard”开始创建项目。
  2. 按照向导提示设置项目名称、位置以及所使用的FPGA设备型号。
  3. 指定项目文件夹,确保路径无中文,以便减少编译过程中的错误。
  4. 选择项目文件类型,通常选择VHDL或Verilog HDL。
  5. 完成向导,进入Quartus II主界面。

在项目创建之后,需要熟悉Quartus II的文件结构,通常一个典型的Quartus II项目包括:

  • HDL源文件(.v或.vhd)
  • IP核文件(.qsys)
  • 编译设置文件(.qsf)
  • 测试仿真文件(.vhd或.v)

2.3.2 设计文件的组织与管理

组织和管理设计文件是项目维护的关键。良好的文件管理习惯能够帮助您快速定位问题,并提高团队协作效率。以下是几个关键点:

  1. 文件命名规范 :为文件设置统一和具有描述性的名称,例如,对于一个名为“TrafficLight”的模块,其文件名可以是“TrafficLight.v”或“TrafficLight.vhd”。
  2. 项目层次结构 :利用Quartus II的层次化设计特性,将项目划分为模块,每个模块都有独立的文件夹,并使用层次化的目录结构管理。
  3. 版本控制 :建议使用版本控制系统管理项目文件,如Git。这样便于跟踪设计的变更历史,以及进行团队协作。
  4. 备份与恢复 :定期备份整个项目文件夹,并在需要时能够恢复到任何特定的状态,这对于避免意外损失至关重要。

通过以上步骤,可以有效地对设计文件进行组织和管理,为开发工作打下坚实的基础。

3. 交通灯控制系统的数字逻辑设计

在现代化城市中,交通灯系统扮演着至关重要的角色,它不仅有助于缓解交通压力,还能提高交通安全,避免交通事故。而数字逻辑设计是实现交通灯系统智能化、自动化管理的基础。本章将深入探讨交通灯控制系统的数字逻辑设计,包括交通灯控制系统的逻辑要求、控制逻辑的实现以及状态机模型的实现。

3.1 交通灯控制系统的逻辑要求

在开始设计之前,首先要清晰理解系统的功能与状态,进而定义系统所需输入输出信号,以构建出完整的逻辑框架。

3.1.1 系统功能与状态分析

交通灯控制系统的主要功能是根据交通流量和行人流量,自动控制交通灯的变化。在实际应用中,一个典型的交通灯控制周期包括红灯、绿灯、黄灯三个状态,且每个状态都会持续一定的时长,以确保交通秩序。另外,还应考虑行人过街的需求,相应设置行人绿灯信号。

3.1.2 输入输出信号定义

为了实现交通灯系统的控制,需要定义一系列输入输出信号。例如,可以定义如下信号:
- 输入信号:行人请求信号、车辆流量检测信号。
- 输出信号:红灯信号、黄灯信号、绿灯信号、行人过街信号。

3.2 交通灯控制逻辑的实现

逻辑设计是交通灯系统设计的核心部分,必须详细分析并实现控制逻辑,以确保系统准确无误地运行。

3.2.1 状态转换图的绘制

状态转换图是描述系统状态变化的图形化表示,它直观地显示了系统状态在各种输入条件下的变化。以下是一个简单的状态转换示意图:

stateDiagram-v2
    [*] --> Red: 开始
    Red --> Green: Time到期
    Green --> Yellow: Time到期
    Yellow --> Red: Time到期

如上图所示,交通灯系统开始时处于红灯状态,经过设定的时间后转换为绿灯,之后再经过一定时间转换为黄灯,最后又回到红灯状态,形成一个完整的循环。

3.2.2 逻辑表达式的推导与简化

为了将上述状态转换逻辑转换为硬件可识别的形式,需要推导出逻辑表达式。简化逻辑表达式能够减少硬件资源的消耗,提高系统的运行效率。例如,若定义以下信号:
- R :红灯信号;
- Y :黄灯信号;
- G :绿灯信号;
- T_R :红灯计时完成信号;
- T_Y :黄灯计时完成信号;
- T_G :绿灯计时完成信号;

那么,各个灯的控制逻辑表达式可以表示为:

always @(posedge clk) begin
    if (T_R) R <= 1;
    else if (T_G) G <= 1;
    else if (T_Y) Y <= 1;
    else begin
        R <= 0;
        G <= 0;
        Y <= 0;
    end
end

通过上述硬件描述语言的逻辑控制,交通灯系统能够准确地进行状态转换。这里使用的是Verilog HDL语言,其在数字电路设计中被广泛使用,能够清晰地描述硬件逻辑。

以上就是第三章的全部内容,详细介绍了交通灯控制系统的数字逻辑设计流程,包括系统逻辑需求分析、状态转换图绘制以及逻辑表达式的推导与简化。在后续章节中,我们将进一步深入了解状态机模型的实现、定时器的设计与实现以及同步与复位逻辑的设计等关键步骤。

4. 状态机模型的实现

4.1 状态机模型的基本原理

4.1.1 有限状态机(FSM)的概念与特征

有限状态机(FSM)是一种计算模型,用于描述系统在不同输入下所经历的状态变化。FSM由一系列状态、输入事件、转移以及输出动作组成。在交通灯系统中,状态机模型可以精确地描述交通灯的循环行为,如红灯亮、绿灯亮等,以及它们之间的状态转换。

FSM的关键特征包括:

  • 状态 :系统能够处于的所有情况的集合,每个状态代表系统的一个稳定阶段。
  • 事件 :触发状态转换的动作或条件。
  • 转移 :事件发生后,系统从一个状态转移到另一个状态的过程。
  • 动作 :系统在特定状态下或特定转移发生时执行的操作。

4.1.2 状态机在交通灯系统中的应用

在交通灯控制系统的应用中,状态机模型用于控制信号灯的变化顺序。根据交通流量、道路规则以及安全需求,交通灯系统需按照一定的顺序改变信号灯的颜色,如红灯变为绿灯,绿灯再变为黄灯,最后回到红灯。这些状态及其转换逻辑可以用状态机很好地表示。

4.2 状态机模型的设计与实现

4.2.1 状态转换表的设计

设计状态机的首要步骤是创建一个状态转换表,该表详细说明了系统在不同输入事件下的状态转换逻辑。对于交通灯系统,状态转换表可能如下所示:

当前状态 输入事件 下一个状态 输出动作
红灯(R) 计时结束 绿灯(G) 点亮绿灯
绿灯(G) 计时结束 黄灯(Y) 点亮黄灯
黄灯(Y) 计时结束 红灯(R) 点亮红灯

此表清晰地展示了交通灯系统中信号灯状态转换的逻辑,以及每个状态下需要执行的动作。

4.2.2 状态机的Verilog HDL编码实现

状态机的逻辑可以通过Verilog HDL进行编码实现。下面是一个简单的状态机编码实例:

module traffic_light_controller(
    input clk,          // 时钟信号
    input reset,        // 复位信号
    output reg red,     // 红灯信号
    output reg yellow,  // 黄灯信号
    output reg green    // 绿灯信号
);

// 状态编码
parameter RED = 2'b00,
          GREEN = 2'b01,
          YELLOW = 2'b10;

// 当前状态和下一个状态变量
reg [1:0] current_state, next_state;

// 状态转移逻辑
always @(posedge clk or posedge reset) begin
    if(reset)
        current_state <= RED;
    else
        current_state <= next_state;
end

// 下一个状态和输出动作逻辑
always @(*) begin
    case (current_state)
        RED: begin
            red = 1; yellow = 0; green = 0;
            next_state = GREEN;
        end
        GREEN: begin
            red = 0; yellow = 0; green = 1;
            next_state = YELLOW;
        end
        YELLOW: begin
            red = 0; yellow = 1; green = 0;
            next_state = RED;
        end
        default: begin
            red = 0; yellow = 0; green = 0;
            next_state = RED;
        end
    endcase
end

endmodule

在上述代码中,我们首先定义了三个信号灯的输出,以及一个状态机的状态。状态变量 current_state next_state 用来表示当前状态和下一个状态。通过时钟上升沿或复位信号来触发状态转移。状态转移逻辑中,每个case分支对应一个状态转换。最终,信号灯根据当前状态输出相应的信号。

这个Verilog代码通过组合逻辑和时序逻辑描述了交通灯的状态机模型,实际开发中需要根据实际的时序要求对代码进行调整和优化。

5. 定时器设计与实现

5.1 定时器在交通灯系统中的作用

5.1.1 定时器的基本概念

在交通灯控制系统中,定时器是核心组件之一,它负责控制信号灯按照既定的时间间隔进行切换,确保交通流的顺畅与安全。定时器的基本概念包括时钟源、计数器和时间参数设定三个部分。时钟源是定时器的基准频率,通常由FPGA板载晶振提供;计数器根据时钟源的频率进行计数,从而实现时间的测量;时间参数设定则是指在设计阶段根据交通流量和法规要求确定的红灯、黄灯、绿灯的持续时间。

5.1.2 定时器的时间参数设定

定时器的时间参数设定取决于交通流量、法规要求和实际交通情况。例如,在主干道上,绿灯的持续时间可能需要更长,以适应较长的车辆队列;而在辅路或行人过街时,则可能设置较短的绿灯和较长的黄灯或红灯时间,以确保行人安全。在设计定时器时,还应考虑异常情况的处理,例如交通拥堵时的延长绿灯时间,以及紧急情况下的强制切换信号等。

5.2 定时器的设计与编码实践

5.2.1 定时器的逻辑设计

在设计定时器时,首先需要确定所需的时钟频率,这通常由FPGA的晶振频率决定。然后根据时钟频率计算计数器的最大值,这个值将决定定时器能够表示的最大时间长度。例如,如果使用一个频率为50MHz的时钟源,一个32位的计数器理论上能够表示的最大时间长度为(2^32 / 50,000,000)秒,约为71.6秒。

设计定时器时,还需要考虑如何设置和读取时间参数,以及如何启动和停止计数器。通常,这些功能可以通过一个状态机来实现,状态机能够根据不同的输入信号控制定时器的状态变化。

5.2.2 定时器的VHDL编码实现

以下是一个简单的VHDL代码示例,展示了如何实现一个基本的定时器逻辑:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL; -- 使用数值库支持无符号数值操作

entity Timer is
    Port ( clk : in STD_LOGIC;          -- 时钟信号
           reset : in STD_LOGIC;        -- 复位信号
           start : in STD_LOGIC;        -- 启动信号
           stop : in STD_LOGIC;         -- 停止信号
           timeout : out STD_LOGIC;     -- 超时输出信号
           timer_value : out unsigned(31 downto 0) -- 当前计数值输出
           );
end Timer;

architecture Behavioral of Timer is
    signal counter : unsigned(31 downto 0) := (others => '0'); -- 计数器信号
begin
    process(clk, reset)
    begin
        if reset = '1' then
            counter <= (others => '0'); -- 同步复位计数器
            timeout <= '0';
        elsif rising_edge(clk) then
            if start = '1' then
                counter <= counter + 1; -- 启动时计数器开始计数
            elsif stop = '1' then
                counter <= (others => '0'); -- 停止时清零计数器
            end if;
            if counter = x"FFFFFFFF" then -- 检查是否达到最大值
                timeout <= '1';
            else
                timeout <= '0';
            end if;
        end if;
    end process;
    timer_value <= counter; -- 输出当前计数值
end Behavioral;

逻辑分析

在这段代码中,我们定义了一个名为 Timer 的实体,它有五个端口: clk 为时钟信号输入, reset 为复位信号输入, start stop 分别控制定时器的启动和停止, timeout 为超时输出信号, timer_value 为当前计数值输出。

在行为架构中,我们定义了一个名为 counter 的信号作为计数器,其宽度为32位,足以表示较长时间间隔。当复位信号为高时,计数器被清零;当时钟上升沿到来且 start 信号为高时,计数器开始计数; stop 信号为高时计数器停止并清零;当计数器的值达到最大值时, timeout 信号被设置为高。

参数说明

  • clk :连接到FPGA板载晶振的时钟信号,决定了定时器的基本时间单元。
  • reset :用于同步复位计数器的信号,使得定时器能够在任何时刻重新开始计数。
  • start stop :分别用于控制定时器的启动和停止,这两个信号可以由系统其他部分的逻辑控制,或直接由外部输入控制。
  • timeout :输出信号,表示定时器是否达到预设的最大计数值,可以用于触发状态转换。
  • timer_value :输出信号,表示当前的计数值,可以用于调试或提供给其他系统组件。

通过上述设计和编码实践,我们实现了一个可配置且功能完备的定时器,能够在FPGA上运行并控制交通灯系统的信号切换。在实际应用中,定时器的设计需要根据具体的交通流量和法规要求进行微调,以达到最佳效果。

6. 同步与复位逻辑

6.1 同步与复位逻辑的重要性

6.1.1 同步机制的作用

在数字电路设计中,同步机制是确保数据在逻辑电路之间安全、准确传输的关键技术之一。由于数字系统中各个部分往往存在不同的时钟域,同步机制能够保障信号在不同时钟域间切换时,数据不会因为时钟偏差而产生不确定的状态,即避免出现亚稳态。同步电路的设计通常涉及信号的同步采样、数据的稳定传递以及边缘检测等技术,它们确保了数据处理的可靠性和系统的稳定性。

6.1.2 复位逻辑的需求分析

复位逻辑是电路初始化的核心,它确保FPGA在上电或异常情况下能够被置于一个已知的、安全的状态。在设计复位逻辑时,需要考虑的因素包括复位类型(同步复位或异步复位)、复位策略(高有效或低有效)、复位信号的去抖动等。合理的复位设计有助于减少设计缺陷,提升系统的可维护性和可靠性。在硬件描述语言中,复位逻辑常常与状态机、存储器等重要模块紧密相关。

6.2 同步与复位逻辑的设计实现

6.2.1 同步电路的设计

设计同步电路时,一个基本的方法是使用双触发器(D触发器)或者多级触发器进行信号的同步采样。这种方法可以有效滤除由于信号变化太快而产生的毛刺,同时将信号稳定地引入到目标时钟域中。在FPGA设计中,采用两级D触发器进行信号同步是常见的设计模式。下面给出一个使用Verilog HDL实现信号同步的示例代码:

module sync_signal(
    input clk_dst,          // 目标时钟域时钟
    input rst_n,            // 复位信号,低有效
    input signal_async,     // 异步输入信号
    output reg signal_sync  // 同步输出信号
);

reg signal_intermediate; // 中间寄存器

always @(posedge clk_dst or negedge rst_n) begin
    if (!rst_n) begin
        signal_intermediate <= 1'b0;
        signal_sync <= 1'b0;
    end else begin
        signal_intermediate <= signal_async;
        signal_sync <= signal_intermediate;
    end
end

endmodule

在上述代码中, signal_async 是需要同步的异步输入信号, signal_sync 是同步后的输出信号。 signal_intermediate 用作中间缓存。每个上升沿,如果复位信号 rst_n 是低电平,则两级寄存器均被清零,否则将输入信号通过两级寄存器同步到目标时钟域。

6.2.2 复位策略的实现

在FPGA设计中,异步复位通常比同步复位具有更高的可靠性,尤其是在面对上电复位和紧急复位的情形时。但异步复位在设计时需要注意避免产生毛刺和竞争条件。下面是一个采用异步复位策略的简单复位模块设计:

module async_reset(
    input clk,          // 时钟信号
    input rst_n,        // 异步复位信号,低有效
    input data_in,      // 输入信号
    output reg data_out // 输出信号
);

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        data_out <= 1'b0; // 异步复位到0
    end else begin
        data_out <= data_in; // 正常工作时,数据通过
    end
end

endmodule

在该复位模块中, rst_n 是复位信号,当其为低电平时,复位发生, data_out 被置为0;一旦复位信号解除,数据输入 data_in 将按正常工作流通过。需要注意的是,异步复位设计需要通过仿真验证在复位信号活跃期间和复位后系统能够按预期工作。

7. 输入输出接口设计

7.1 输入输出接口的基本要求

7.1.1 接口设计的原则与方法

在FPGA项目中,设计输入输出(I/O)接口时必须遵循一些基本原则,以确保信号的完整性和系统的可靠性。首先,接口必须与外部设备的电气特性相匹配,包括电压水平、电流负载能力和信号转换速度等。其次,设计时还需考虑信号的同步与去抖动问题,防止由于噪声或不规则的信号变化导致的误操作。此外,为了实现不同功能模块之间的数据传输,接口设计需要兼容相应的通信协议。

7.1.2 信号完整性与接口保护

信号完整性问题是接口设计中的一个重要方面,它涉及到信号在传输过程中保持原有特性的能力。解决信号完整性问题通常需要在设计时注意信号的走线、阻抗匹配、电源分配以及避免串扰等。同时,接口保护措施也必不可少,例如使用二极管、TVS(瞬变抑制二极管)、ESD(静电放电)保护电路等,可以避免由于外部过压或静电干扰导致的硬件损坏。

7.2 输入输出接口的实现

7.2.1 输入接口电路的设计与实现

设计输入接口时,通常会考虑使用信号调理电路,比如输入缓冲器,以便对信号进行适当的放大和调整。例如,如果FPGA工作在较低电压级别(如3.3V或1.8V),而外部输入信号来自更高电压的设备(如5V),那么就需要一个逻辑电平转换器来保证信号的正确读取。此外,可以实现输入去抖动电路,例如使用简单的RC滤波器或数字滤波算法,来消除噪声引起的误触发。

// 输入信号去抖动的简单Verilog实现
module debounce(
    input clk,          // 时钟信号
    input noisy_signal,  // 带噪声的输入信号
    output reg clean_signal // 清理后的输出信号
);

// 参数定义
parameter DEBOUNCE_THRESHOLD = 100000; // 去抖动阈值

// 寄存器定义
reg [15:0] counter; // 计数器
reg last_state;     // 上一次输入状态

// 主逻辑
always @(posedge clk) begin
    if (noisy_signal != last_state) begin
        counter <= counter + 1;
        if (counter >= DEBOUNCE_THRESHOLD) begin
            clean_signal <= noisy_signal;
            counter <= 0; // 重置计数器
        end
    end else begin
        counter <= 0; // 如果输入稳定,重置计数器
    end
    last_state <= noisy_signal;
end

endmodule

7.2.2 输出接口电路的设计与实现

输出接口设计应确保FPGA能够驱动外部负载。在很多情况下,FPGA的输出电流不能直接满足外部设备的需求,因此可能需要使用晶体管或继电器来驱动较重的负载。同时,为了保护FPGA,输出接口设计还需包括限流电路或电压限制电路。例如,在输出接口电路中加入一个外部电流限制电阻,可以防止短路时对FPGA输出端口造成过大电流冲击。

在设计输出接口时,还需要考虑输出信号的转换速率。为了减少电磁干扰(EMI),可能需要对输出信号进行缓冲,以限制信号的边沿速率。这通常通过在输出驱动器前加入一个小的RC滤波网络来实现。

输入输出接口的优化是一个持续的过程,需要不断地测试和调整以达到最优效果。下一章节我们将深入探讨VHDL和Verilog HDL编码实践,如何将理论应用到实际的FPGA设计中。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:本文将详细介绍如何使用Altera公司的Quartus II 6.0软件,结合VHDL或Verilog硬件描述语言,设计一个高效的十字交叉路口三色交通灯控制系统。文章将指导读者了解整个设计流程,包括创建项目、编写HDL代码、编译与仿真、布局与布线,直至下载测试和调试优化。掌握这一课程设计,不仅可以学习到数字逻辑设计的基础知识,而且能深入理解状态机、定时器、输入输出接口等核心概念。


本文还有配套的精品资源,点击获取
menu-r.4af5f7ec.gif

更多推荐