欢迎来到淘文阁 - 分享文档赚钱的网站! | 帮助中心 好文档才是您的得力助手!
淘文阁 - 分享文档赚钱的网站
全部分类
  • 研究报告>
  • 管理文献>
  • 标准材料>
  • 技术资料>
  • 教育专区>
  • 应用文书>
  • 生活休闲>
  • 考试试题>
  • pptx模板>
  • 工商注册>
  • 期刊短文>
  • 图片设计>
  • ImageVerifierCode 换一换

    VHDL参考资料精品资料.doc

    • 资源ID:96699047       资源大小:907.25KB        全文页数:183页
    • 资源格式: DOC        下载积分:15金币
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录   QQ登录  
    二维码
    微信扫一扫登录
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    VHDL参考资料精品资料.doc

    VHDL 语言 前言1VHDL语言简介 VHDL语言(VHSIC Hardware Description Language,甚高速集成电路硬件描述语言)是一种设计、仿真、综合的标准硬件描述语言,是对可编程逻辑器件进行开发与设计的重要工具,其优点是:支持自上而下和基于库的设计,支持范围广,具有多层次描述系统硬件功能的能力。VHDL语言已成为IEEE的一种工业标准,是实现信息系统硬件开发所必备的知识和技能。2本课程的主要内容:l 数字系统硬件设计描述l VHDL语言程序的基本结构l VHDL语言的数据类型与运算操作符l VHDL语言构造体的描述方式l VHDL语言的主要描述语句l 基本逻辑电路设计l 仿真与逻辑综合l MAXPLUS II 使用说明l ACTIVE HDL 使用说明l 电路设计实例3 参考教材VHDL硬件描述语言与数字逻辑电路设计 侯伯亨 顾新 西安电子科技大学出版社 1999;VHDL编程与仿真王毅平 张振荣 人民邮电出版社 2000年7月 第一章 数字系统硬件设计概述1. 1 传统的系统硬件设计方法l 采用自下而上(ottom )的设计方法l 采用通用的逻辑元、器件l 在系统硬件设计的后期进行仿真和调试l 主要设计文件是电原理图12 利用硬件描述语言()的硬件电路设计方法l 硬件描述语言:可以描述硬件电路的功能,信号连接关系和定时关系的语言。利用硬件描述语言编程来表示逻辑器件与系统硬件的功能和行为,是该设计方法的一个重要特征。l 采用自上而下(op Down)的设计方法 就是从系统的总体要求出发,自上而下地逐步将设计内容细化,最后完成系统硬件的总体设计。l 设计的三个层次: 第一层次是行为描述。实质上就是对整个系统的数学模型的描述(抽象程度高)。 第二层次是RTL方式描述,又称寄存器传输描述(数据流描述),以实现逻辑综合。 第三层次是逻辑综合,就是利用逻辑综合工具,将RTL方式描述的程序转换成用基本逻辑元件表示的文件(门级网络表)。在门电路级上再进行仿真,并检查定时关系。l 完成硬件设计的两种选择: 由自动布线程序将网络表转换成相应的ASIC芯片制造工艺,作出ASIC芯片。将网络表转换成FPGA编程代码,利用FPGA器件完成硬件电路设计。l 自上而下硬件设计流程 规格设计 行为级描述 行为级仿真 RTL级描述 RTL级仿真 逻辑综合优化 门级仿真 定时检查 输出门级网表l HDL语言设计硬件电路的优点: 系统中可大量采用芯片 采用系统早期仿真 降低了硬件电路设计难度13 VHDL语言设计硬件电路的优点l 美国国防部1982年开发VHDL(Very -High-Speed Integrated Circuit Hardware Description Language)语言,是当前广泛使用的HDL语言之一,并被IEEE和美国防部采用为标准的HDL语言。l 设计技术齐全、方法灵活、支持广泛l 系统硬件描述能力强l 可以与工艺无关编程l 语言标准、规范、易于共享和复用 第二章 VHDL语言程序的基本结构21 VHDL语言设计的基本单元及其构成l 一个完整的VHDL语言程序通常包含实体(Entity)、构造体(Architecture)、配置(Configuration)、包集合(Package)和库(Library):l 功能: 实体 - 用于描述所设计的系统的外部接口信号;构造体 用于描述系统内部的结构和行为;包集合 存放各设计模块都能共享的数据类型、常数和子程序库;配置 用于从库中选取所需单元来组成系统设计的不同版本;库 存放已经编译的实体、构造体、包集合和配置。l 基本组成:实体说明和构造体两部分 实体说明(接口) 构造体(实现)1 实体说明:规定此实体输入与输出的数目与类型。l 结构: entity 实体名 isgeneric(类属参数说明);port(端口说明);end实体名;l 类属参数说明:generic ( 常数名:数据类型:数值);在端口说明前,用于指定参数。l 端口说明: 在entity语句的实体说明部分,常用port语句描述实体对外界连接的端口(数目、方向和数据类型)。port (端口名:端口方向端口数据类型;端口名:端口方向端口数据类型;);端口方向:in (输入),只能读,用于:时钟输入、控制输入(装入、复位、使能)、单向数据输入;out (输出),只能被赋值,用于不能反馈的输出;inout(输入输出) ,既可读又可被赋值,被读的值是端口输入值而不是被赋值,作为双向端口。buffer(缓冲),类似于输出,但可以读,读的值是被赋值,用做内部反馈用,不能作为双向端口使用。l 例1):entity NAND2 is port(A,B: in BIT; Z: out BIT);end NAND2;l 例2):-Define an entity (design) called COMP -that has 2 N-bit input and one output.entity COMP is generic(N : INTEGER :=8 ) ; - default is 8 bits port ( x, y : in BIT_VECTOR ( 0 to N-1); equal : out BOOLEAN );end COMP; 2. 构造体构造体定义实体功能的一种实现。l 构造体的结构:architecture 构造体名of 实体名 is块说明项begin 并发语句end 构造体名;l 块说明项(或定义语句),位于architecture 和begin之间,对构造体内部的使用信号、常数、数据类型和函数进行说明,包括:使用语句子程序说明子程序体类型说明子类型说明常数说明信号说明元件说明l 并行语句处于begin 与end之间,描述构造体的行为与连接关系。l 构造体的描述方法: 行为描述(按算法的路径来描述); 数据流描述或RTL描述(采用寄存器传输描述); 结构化描述(采用例化元件) 例化(instantiation ):在高层次的设计中调用低层次的实体作为元件的过程。l 构造体的组织 构造体说明 说明在并行语句间或并行语句与接口端口之间所使用的信号。说明构造体中使用的类型、常数、和子程序。并行语句 元件例化block将并行语句集中在一起 进程 信号赋值 过程调用l 例entity COUNTER3 isport( clk: in bit; reset : in bit; count: out integer range 0 to 7);end COUNTER3;architecture MY_ARCH of COUNTER3 issignal count_tmp : integer range 0 to 7;begin process begin wait until (clk'event and clk='1'); if reset='1' or count_tmp =7 then count_tmp<=0; else count_tmp<=count_tmp + 1; end if; end process; count<=count_tmp;end MY_ARCH;注:构造体中的信号和常数名不能与实体端口名相同。2.2 语言结构体的子结构描述1. block语句结构l 语句结构:块结构名:block begin . . .end block 块结构名;2. 进程(process)语句结构l 进程语句的结构:进程名:process(信号,信号,) 说明内部变量begin顺序语句 end process;l 进程的组织进程 说明:按计算顺序暂存的变量,以及局部使用的数据类型、常数、元件及子程序顺序语句 LOOP 语句 信号赋值 NEXT语句 过程调用 EXIT语句 变量赋值 WAIT 语句 IF 语句 NULL 语句 CASE 语句l 功能独立的电路可用进程来描述l 进程中语句的顺序性l 进程的启动*敏感表*敏感表中信号的变化将启动进程语句*启动后,语句从上到下逐句执行,最后一个语句执行完毕后,返回进程开始的语句,等待下一次敏感表的变化。l 进程的同步描述同一结构体中有多个进程存在时,进程之间可一边进行通信,一边并行同步执行。子程序(subprogram)语句结构描述 两种类型:过程(procedure) 函数 (function)l 过程语句结构:procedure 过程名(参数1,参数2,) is 定义语句;begin 顺序处理语句;end 过程名;*参数可以是输入也可以是输出*例: 将位矢量转换为整数procedure vector_to_int (z : in std_logic_vector; x_flag : out boolean; q : inout integer) isbegin q:=0; x_flag:=false; for i in z' range loop q:=q*2; if (z(i)=1) then q:=q+1; elsif(z(i)/=0) then x_flag:=true; end if; end loop;end vector_to_int; 循环次数由z的位数决定,z(0)为最高位。l 函数语句结构:function 函数名(参数1,参数2,) return 数据类型名 is 定义语句;begin 顺序处理语句; return 返回变量名end 函数名;*参数为输入参数*通常集中在包集合中 *例:将boolean型信号转换到 bit型function b12bit(a: Boolean) return BIT is begin if a then return '1' else return '0' end if; end b12bit;2.3 包集合、库与配置 库库(Library)是经编译后的数据的集合,库说明总是放在设计单元的最前面。1) 库的种类:l IEEE 库 包含:STD_LOGIC_1164 STD_LOGIC_ARITH STD_LOGIC_UNSIGNEDl STD库 包含:STANDARD包集合 TEXTIO 包集合 TEXTIO 包集合使用例: LIBRARY STD; USE STD.TEXTIO. ALL;l ASIC矢量库各公司提供的ASIC称逻辑门库l WORK 库为现行作业库,存放设计者的VHDL语言程序l 用户定义的库用户为自身设计需要所开发的共用包集合和实体。2) 库的使用l 除WORK、STD库外,首先要说明。格式: library 库名; use 库名.包名.项目名;例: library ieee; use ieee.std_logic_1164.all;l 库说明的作用范围:从实体开始到其所属构造体、配置为止。 包集合l 包集合用于封装属于多个设计单元分享的公共信息。l 包集合由包说明(说明数据类型、子程序和常量等)和包体(它含有子程序体与现有的延时常数)所组成。子程序由执行公共操作的过程和函数组成。包集合是分享属于实体数据的一种机制,把子程序、数据类型和元件说明看成建立设计的工具,则包集合可看成工具箱。 1) 包集合的结构: package 包集合名 is 包集合说明语句; end 包集合名; package body 包集合名 is 包集合体说明语句; end 包集合名;注:包集合体为可选项。3) 包集合的使用: use work.包集合名.all;例:l 建一个包集合。此例中,用字母符号代表用于控制的二进编码序列。library ieee;use ieee.std_logic_1164.all;-ALU source operand control mnemonicspackage mnemonics0 isconstant aq: std_logic_vector(2 downto 0) :="000"constant ab: std_logic_vector(2 downto 0) :="001"constant zq: std_logic_vector(2 downto 0) :="010"constant zb: std_logic_vector(2 downto 0) :="011"constant za: std_logic_vector(2 downto 0) :="100"constant da: std_logic_vector(2 downto 0) :="101"constant dq: std_logic_vector(2 downto 0) :="110"constant dz: std_logic_vector(2 downto 0) :="111"end mnemonics0;l 编译通过后即可使用。注:maxplus2在编译此package时,报告: "does not contain an architecture bodystopping compilation",但此package 将被正确分析,并可成功地编译使用此package的其他设计。 l 用于其他使用此包集合的程序:-由控制信号控制两个多路选择器library ieee;use ieee.std_logic_1164.all;use work.mnemonics0.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;entity src_op is port( d,ad,bd,q: in unsigned(3 downto 0); src_ctl: in std_logic_vector(2 downto 0); r,s: buffer unsigned(3 downto 0);end src_op;architecture src_op of src_op isbeginwith src_ctl select r <= ad when aq | ab, "0000" when zq | zb | za, d when others;with src_ctl select s <= q when aq | zq | dq, bd when ab | zb , ad when za |da, "0000" when others;end src_op;配置描述层与层之间的连接关系以及实体与构造体之间的连接关系。在仿真时利用配置选择不同的构造体。格式:CONFIGURATION 配置名 OF 实体名 ISFOR 构造体名END FOR; END 配置名;l 例configuration MY_CONFIG of COUNTER3 is for MY_ARCH end for;end MY_CONFIG;第3章 VHDL语言的数据类型及运算操作符31 VHDL语言的客体(或对象)及其分类l 可以赋予一个值的对象成为客体(object)。l 客体包括: 信号(signal ):是连接实体(或进程)的主要机制,用信号在实体(或进程)之间传送信息;变量 (variable):变量对象位于进程和子程序中, 主要用于局部计算结果的暂存。 常数 (constant):命名数据类型的一种特殊值。l 客体的含义与说明:客体说明 含 义 说 明 场 合 信号 全局量architecture, package, entity 变量 局部量process, function, procedure 常数全局量、 局部量 包括上面两种场合l 客体说明格式:客体类别 客体名 数据类型:=初始值*客体类别:信号、变量或常数;*客体名:客体的名称;*数据类型:(见后面数据类型)*初始值:(可先赋初始值)1.常数(constant)l 格式: constant 常数名:数据类型:=初始值;l 例: constant VCC : real:=5.0; constant delay,delay:Time:=10ns; *常数赋值后不能变; *赋的值要与数据类型一致; *常数有和信号一样的可视性规则,在程序包中说明的常数为全局量;在实体说明部分的常数可以被该实体中任何构造体引用,在构造体中的常数能被其构造体内部任何语句采用,包括被进程语句采用;在进程说明中说明的常量只能在进程中使用。2变量 *只能在进程、函数或过程中使用; *用做局部的数据存储,为局部量, *赋值立即生效。l 格式: Variable变量名:数据类型 约束条件 :=表达式;l 例:Variable x,y:integer;Variable count:integer range 0 to 255:=10; 信号*信号数据对象:把实体连在一起形成模块,信号是实体间动态数据交换的手段; *除无方向说明外,与端口概念一致; *通常在构造体、包集合、实体中说明。全局信号在程序包中说明,它们被所属的实体分享。l 格式:l signal变量名:数据类型约束条件:=初始值; 即在关键词SIGNAL后跟一个或者多个信号名,每个信号名将建一个新信号,用冒号:把信号名和信号的数据类型分隔开,信号数据类型规定信号包含的数据类型信息,最后信号还可包含初始化信号指定的初值。l 例: signal ground:bit:='0' signal en :std_logic_vector(7 downto 0); *信号赋值有附加延迟; *信号为全局量,可实现进程之间的通信; *程序中赋值采用 <= 。4延迟l 进程中向信号赋值的时刻和信号得到该值的时刻之间有延迟;l 当向信号赋值时未给定延迟,但有一隐含延迟,称延迟;l 延迟是一个无穷小的时间量;5信号与变量的区别l 变量赋值立即发生,无延迟;信号赋值至少有延迟,在进程中仅当碰到wait语句或进程结束赋值才生效。l 进程只对信号敏感,而对变量不敏感。l 信号除当前值外还有许多相关信息,而变量只有当前值。l 信号是全局量,变量为局部量。l 信号在电路中的功能是保存变化的数值和连接子元件;变量在电路中无类似的对应关系,用于计算。l 例1:library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;entity test_01 is port( a: in integer range 0 to 2; c: in integer range 0 to 2; b: in integer range 0 to 2; x: out integer range 0 to 4; y: out integer range 0 to 4);end test_01;architecture test_01 of test_01 issignal d:integer range 0 to 2;beginprocess(a,b,c,d)begin d<=a; x<=b+d; d<=c; y<=b+d;end process;end test_01;结果:l a不起作用;*x<=b+c; y<=b+c;l 例2:use ieee.std_logic_unsigned.all;entity test_02 is port( a: in integer range 0 to 2; c: in integer range 0 to 2; b: in integer range 0 to 2; x: out integer range 0 to 4; y: out integer range 0 to 4);end test_02;architecture test_02 of test_02 isbeginprocess(a,b,c)variable d: integer range 0 to 2;begin d:=a; x<=b+d; d:=c; y<=b+d;end process;end test_02;结果: x<=b+a; y<=b+c;l 例3:library ieee;use ieee.std_logic_1164.all;entity test_03 is port( a,clk,reset: in std_logic; b: out std_logic);end test_03;architecture test_03 of test_03 issignal shif_1,shif_2,shif_3:std_logic;beginprocess(clk)begin if(reset='1') then shif_1<='0' shif_2<='0' shif_3<='0' b<='0' elsif (clk'event and clk='1') then shif_1<=a; shif_2<=shif_1; shif_3<=shif_2; b<=shif_3; end if;end process;end test_03;运行结果如下图:32 VHDL语言的数据类型1.标准数据类型 数据类型 含 义 整 数(integer) 自然数(natural) 正整数(positive) -2147483647-2147483647 0 - 2147483647 1- 2147483647 实 数浮点数,-1。0E+38-+1。0E+38 位逻辑“0”或“1” 位矢量位矢量 布尔量逻辑“假”或“真” 字 符ASCII字符 时 间时间单位fs,ps,ns,us,ms,sec,min,hr 错误等级NOTE,WARNING,ERROR,FAILURE 字符串字符矢量l VHDL中的预定义类型,用户不必明显地说明就可直接使用,在STANDARD 程序包中。l 整数(integer)l 整数类型的行为和算术中整数相似 *范围: -2147483647-2147483647l 自然数(natural) *范围: 0-2147483647l 正整数(positive) *范围: 1-2147483647l 布尔类型: 实际是一个两值(false和true)的枚举型;无数值含义,不能进行算术运算,能进行关系运算。l 位(bit): 表示:''或''.l 位矢量(bit_vector)用双引号括起来的一组位数据,例:"00110",X"00BB"。l 字符(character) 用单引号括起; 大、小写含义不同; 包括:到中的字母、到中的数字、空白及特殊字符。l 字符串(string)用双引号括起;l 时间: 物理型数据(物理类型表示如距离、电流和时间一类的物理量),包含整数与单位两部分,例如:55 sec,2 min.l 错误等级:表征系统状态,共四种:(Note,Warning,Error,Failure),编译与仿真时用。2 用户定义的数据类型l 格式:type 数据类型名,数据类型名 数据类型定义;不能进行逻辑综合*枚举(enumerated)类型*整数(integer)类型*实数(real)(float)类型*数组(array)类型*存取(access)类型*文件(file)类型*时间(time)类型*记录(recorde)类型l 枚举(enumerated)类型 枚举类型是抽象数据类型,它描述用户定义的操作并使模块更可读,此类型通过列出(或枚举)该类型中所有元素来定义。*格式: TYPE 数据类型名 IS (元素,元素,);*“数据类型名”可用字母、下划线和数组成的序列,且必须以字母开头,也不能用VHDL保留字。元素是单字符或字符串。若为单字符则外加单引号。*例: TYPE STD_LOGIC IS ('U','X','0','1','Z','W','L','H','-'); TYPE week IS (sun,mon,tue,wed,thu,fri,sat); TYPE four IS ('a','b','c','d'); TYPE color IS (red,yellow,green)*在有限状态机中最常用。l 整数(integer)类型*格式: TYPE 数据类型名 IS integer 约束范围;*例: TYPE digit IS integer rangeto;l 实数(real)(float)类型l 实型类型行为和算术中的实数类似格式: TYPE 数据类型名 IS real 约束范围;*例: TYPE digit IS realrange-1E4 TO 1E4;l 数组(array)类型*属于复合类型,数组是相同类型元素的分组。*有约束数组:(数组序号范围明显规定)格式: TYPE 数组名 IS array(整数范围)of 元素类型名 ; “数组名”为新的有约束数组名,“整数范围”为整数类型的子范围,“元素类型名”为每一个数组元素的类型。例: type data_bit is array(0 to 5) of bit; type data_bit is array(15 downto 0) of bit; type str is array(1 to 20) of character;*无约束数组: 在类型说明中没有完全指定类型的范围(或者说尺寸),数组序号范围是一个数据类型(例如整型等)。这允许多个子类型分享一个公共的基本类型,然后实体和子程序能在各种不同的子类型上工作,从而代替了写每种尺寸大小的子程序或实体。格式: TYPE 数组名 IS array(范围类型名 range < >)of 元素类型名 ; “数组名”为新的有约束数组名,“范围类型名”为整数类型或子类型,“元素类型名”为每一个数组元素的类型。例1: TYPE BIT_VECTOR IS ARRAY (NATURAL RANGE < > ) OF BIT; 这里,数组的元素数目没有指定,表示用RANGE < >方式,这种表示方式指出定义的类型有一个非限定的范围。关键字NATURAL在类型说明中指出该类型范围仅由NATURAL的范围指定(从0到一个最大整数值)。 无约束类型一般用于子程序变元的类型或实体端口。例2: type bit_vector is array(integer range < >) of bit;*多维数组:格式: TYPE 数组名 IS array(数值范围1,数值范围2,)of 原数据类型名 ;例: type data_bit is array(0 to 15,0 to 15) of bit; type data_bit is array(15 downto 0,15 downto 0) of bit;l 时间(time)类型*格式: TYPE 数组名 IS 范围 ; UNITS 基本单位; 单位; END UNITS;*例: type time is range 2147483647 to 2147483647 units fs; ps=1000 fs; ns=1000 ps; us=1000 ns; ms=1000 us; sec=1000 ms; min=60 sec; hr=60 min;end units; * architecture eaxample of example is begin process(x) variable s: time; begin a:=1 fs; a:=1 ns; a:=1 sec; a:=1 min; end process; end example;l 记录(recorde)类型*属于复合类型,记录是不同类型元素的分组。*格式: TYPE 记录类型名 IS RECORD 元素名1:数据类型名 ; 元素名2:数据类型名 ; 。 。 END RECORDE ; 3用户定义的子类型l 子类型能对基本类型的范围加限制。l 格式:SUBTYPE 子类型名 IS 数据类型名范围;l 是对原数据类型指定范围而形成,或与原类型范围一致。l 例:subtype inter is integer range 0 to 100;subtype inter is integer ;subtype abus is std_logic_vector(7 downto 0);4数据类型的转换l 不同类型的数据必须在类型转换后才能进行运算或操作。l 类型转换函数表: 函 数 名 功 能l std_logic_1164包集合TO_STDLOGICVECTOR(A)TO_BITVECTOR(A)TO_STDLOGIC(A)TO_BIT(A) 由 BIT_VECTOR转换成 STD_LOGIC_VECTOR 由 STD_LOGIC_VECTOR转换成 BIT_VECTOR 由 BIT转换成 STD_LOGIC 由 STD_LOGIC 转换成 BIT l std_logic_arith包集合CONV_STD_LOGIC_VECTOR(A,位长 )CONV_INTEGER(A)由INTEGER ,UNSIGNED,SIGNED转

    注意事项

    本文(VHDL参考资料精品资料.doc)为本站会员(封****n)主动上传,淘文阁 - 分享文档赚钱的网站仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知淘文阁 - 分享文档赚钱的网站(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于淘文阁 - 版权申诉 - 用户使用规则 - 积分规则 - 联系我们

    本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

    工信部备案号:黑ICP备15003705号 © 2020-2023 www.taowenge.com 淘文阁 

    收起
    展开