基于CORDIC算法的SIN和COS函数的设计

1.系统设计要求

1)设计一个应用CORDIC算法求解正弦函数sinθ和余弦函数cosθ的VHDL程序。

2)CORDIC算法简介

在现代信号处理中,经常会遇到三角函数、超越函数和坐标转化等问题。传统的实现方法有查找表、多项式展开等方法。这些方法在精度、速度、简单性和效率方面往往不能兼顾,而CORDIC算法则可以很好地兼顾这几方面的要求。    

CORDIC是坐标旋转数字计算机(Coordinate Rotations Digital Computer)的英文字头缩写,它于1959年由J.Volder提出,首先应用于导航系统,使得矢量的旋转和定向运算不需要做复杂运算。

CORDIC算法的基本思想是通过一系列固定的、与运算基数相关的角度偏摆来逼近所需的旋转角度。可通过该算法的圆周模式、双曲线模式、线性模式等不同的实现模式,来计算乘除、平方根、正弦、余弦、反正切向量旋转以及指数运算等。由于基本运算单元只有移位与加减法,这就为CORDIC算法的FPGA实现打下了良好的基础。

       2.CORDIC算法实现结构 

CORDIC算法的实现有两种结构方案:迭代结构和流水线结构。

基于迭代结构的CORDIC算法实现方案只需要一组移位及加减运算的单元,硬件开销很小,但控制比较复杂,而且完成一次CORDIC运算需要多个时钟周期,当对速度要求较高时很难满足要求。

基于流水线结构的实现方案,每级CORDIC迭代运算都使用单独的一套运算单元,与基于迭代结构的实现方案相比,流水线结构的处理速度非常快,当流水线填满之后每个时钟周期就会计算出一组结果。

本设计采用流水线结构进行设计:

外部输入XI、YI、ZI作为第一级流水线单元的输入X(0)、Y(0)、Z(0);

中间各个单元首尾相接,也就是第N个单元的输入与N-1个单元的输出X(N-1), Y(N-1), Z(N-1)相连,第N个单元的输出X(N), Y(N), Z(N)又与N+1个单元的输入相连;

最后一级处理单元的输出X(N)、Y(N)、Z(N)就是整个系统的输出XO、YO、ZO。

   先设计一个根据已知的( Xn-1,Yn-1,Zn-)求解( Xn,Yn ,Zn )的通用流水单元电路程序CORDICPIPE.VHD,再利用N个单元电路构成流水线,实现由(X0,Y0 ,Z0 )求解( Xn,Yn ,Zn )的CORDIC算法实现电路程序CORDIC.VHD,最后给CORDIC算法实现电路赋予确定的初值(0.60725,0,角度 ),构建一个求解正弦和余弦函数的顶层电路程序

        3 . 主要模块的设计思想与源程序设计

--CORDIC.VHDL
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
 ENTITY CORDIC IS
	GENERIC(PIPELINE:INTEGER:=15;
					WIDTH:INTEGER:=16);
	PORT(CLK:IN STD_LOGIC;
			ENA:IN STD_LOGIC;
			XI:IN SIGNED(WIDTH-1 DOWNTO 0);
			YI:IN SIGNED(WIDTH-1 DOWNTO 0):=(OTHERS=>'0');
			ZI:IN SIGNED(WIDTH-1 DOWNTO 0);
			XO:OUT SIGNED(WIDTH-1 DOWNTO 0);
			YO: OUT SIGNED(WIDTH-1 DOWNTO 0));
	END ENTITY CORDIC;
ARCHITECTURE ART OF CORDIC IS
	TYPE XYVECTOR IS ARRAY(PIPELINE DOWNTO 0)OF
	SIGNED(WIDTH-1 DOWNTO 0);
	TYPE ZVECTOR IS ARRAY(PIPELINE DOWNTO 0)OF
	SIGNED(19 DOWNTO 0);
	COMPONENT CORDICPIPE
	GENERIC(WIDTH:NATURAL:=16;
				PIPEID:NATURAL:=1);
	PORT(CLK:IN STD_LOGIC;
			ENA:IN STD_LOGIC;
			XI:IN SIGNED(WIDTH-1 DOWNTO 0);
			YI:IN SIGNED(WIDTH-1 DOWNTO 0);
			ZI:IN SIGNED(19 DOWNTO 0);
			XO: OUT SIGNED(WIDTH-1 DOWNTO 0);
			YO:OUT SIGNED(WIDTH-1 DOWNTO 0);
			ZO:OUT SIGNED(19 DOWNTO 0));
	END COMPONENT CORDICPIPE;
	SIGNAL X,Y:XYVECTOR;--定义模块间连接信号,用于16个流水线单元电路的级联
	SIGNAL Z:ZVECTOR;
	BEGIN
 --FILL FIRST NODES
 --FILLX
	X(0)<=XI;  --将外部输入xi赋值给第一级流水线单元的输入X(0)
 --FILL Y
	Y(0)<=YI;--将外部输入Yi赋值给第一级流水线单元的输入Y(0)
 --FILLZ
	Z(0)(19 DOWNTO 4)<=ZI;
 --把外部输入赋值给第一级流水线单元的输入
	Z(0)(3 DOWNTO 0)<=(OTHERS=>'0');
 --GENERATE PIPELINE
	GEN_PIPE: FOR N IN 1 TO PIPELINE GENERATE
		PIPE:CORDICPIPE
			GENERIC MAP(WIDTH=>WIDTH,PIPEID=>N-1)
			PORT MAP(CLK,ENA,X(N-1),Y(N-1),Z(N-1),X(N),Y(N),Z(N));
	END GENERATE GEN_PIPE;
 --ASSIGN OUTPUTS
	XO<=X(PIPELINE);
 --复制了16个相同的单元电路,并且各个单元首尾相接,构成流水线结构
	YO<=Y(PIPELINE);
 END ARCHITECTURE ART;
--CORDICPIPE.VHD   流水线模块
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
ENTITY CORDICPIPE IS
	GENERIC(WIDTH:NATURAL:= 16;  --类属表
					PIPEID:NATURAL:=1);
 PORT(CLK:IN STD_LOGIC;
			ENA:IN STD_LOGIC;
			XI:IN SIGNED(WIDTH-1 DOWNTO 0);
			YI:IN SIGNED(WIDTH-1 DOWNTO 0);
			ZI:IN SIGNED(19 DOWNTO 0);
			XO:OUT SIGNED(WIDTH-1 DOWNTO 0);
			YO:OUT SIGNED(WIDTH-1 DOWNTO 0);
			ZO:OUT SIGNED(19 DOWNTO 0));
 END ENTITY CORDICPIPE;
 ARCHITECTURE ART OF CORDICPIPE IS
 --FUNCTION CATAN (CONSTANTE ARC-TANGENT).
 --THIS IS A LOOKUP TABLE CONTAINING PRE-CALCULATED ARC-TANGENTS.   
 --N IS THE NUMBER OF THE PIPE,RETURNED IS A20BIT ARC-TANGENT VALUE.
 --THE NUMBERS ARE CALCULATED AS FOLLOWS:Z(N)=ATAN(I/2^N)
 --EXAMPLES:
 --20BIT VALUES=>2~20=2PI(RAD)
 --1(RAD)=2~20/2PI=166886.053...
 --N:O,ATAN(I/1)=0.7853..(RAD)
 --0.7853..*166886.053..=131072(DEC)=20000(HEX)
 --N:1,ATAN(I/2)=0.4636.(RAD)
 --0.4636..*166886.053..=77376.32(DEC)= 12E40(HEX)
 --N:2,ATAN(1/4)=0.2449.(RAD)
 --0.2449..*166886.053.=40883.52(DEC)= 9FB3(HEX)
 --N:3,ATAN(1/8)=0.1243..(RAD)
 --0.1243..*166886.053..=20753.1I(DEC)=5111(HEX)
 FUNCTION CATAN(N:NATURAL) RETURN INTEGER IS
	VARIABLE RESULT:INTEGER;           --根据迭代步骤N的值求解该步需要旋转的角度,提高一个预计算的CASE查表
	BEGIN
	CASE N IS
		WHEN 0=> RESULT:=16#020000#;
		WHEN 1=> RESULT:=16#012E40#;
		WHEN 2=> RESULT:=16#09FB4#;
		WHEN 3=> RESULT:=16#05111#;
		WHEN 4=> RESULT:=16#028B1#;
		WHEN 5=> RESULT:=16#0145D#;
		WHEN 6=> RESULT:=16#0A2F#;
		WHEN 7=> RESULT:=16#0518#;
		WHEN 8=> RESULT:=16#028C#;
		WHEN 9=> RESULT:=16#0146#;
		WHEN 10=> RESULT:=16#0A3#;
		WHEN 11=> RESULT:=16#051#;
		WHEN 12=> RESULT:=16#029#;
		WHEN 13=> RESULT:=16#014#;
		WHEN 14=> RESULT:=16#0A#;
		WHEN 15=> RESULT:=16#05#;
		WHEN 16=> RESULT:=16#03#;
		WHEN 17=> RESULT:=16#01#;
		WHEN OTHERS=>RESULT:=16#0#;
 END CASE;
 RETURN RESULT;
 END CATAN;
 --FUNCTION DELTA IS ACTUALLY AN ARITHMATIC SHIFT RIGHT
 FUNCTION DELTA(ARG:SIGNED;CNT:NATURAL)RETURN SIGNED IS   --根据输入ARG和CNT求解ARG/2^CNT  
	VARIABLE TMP:SIGNED(ARG'RANGE);
	CONSTANT LO:INTEGER:=ARG'HIGH-CNT+1;
	BEGIN
	FOR N IN ARG'HIGH DOWNTO LO LOOP
	TMP(N):=ARG(ARG'HIGH);    --将右移后空余各位补符号位
	END LOOP;
	FOR N IN ARG'HIGH-CNT DOWNTO 0 LOOP
	TMP(N):=ARG(N+CNT);       --TMP的数据右移的CNT位
	END LOOP;
	RETURN TMP;
	END FUNCTION DELTA;
	FUNCTION ADDSUB(DATAA,DATAB:IN SIGNED;ADD_SUB:IN STD_LOGIC)  --根据信号的不同将DATAA和DATAB做加法和减法
	RETURN SIGNED IS
	BEGIN
	IF(ADD_SUB='1')THEN
	RETURN DATAA+DATAB;
	ELSE
	RETURN DATAA-DATAB;
	END IF;
	END FUNCTION ADDSUB;
	SIGNAL DX,XRESULT:SIGNED(WIDTH-1 DOWNTO 0);
	SIGNAL DY,YRESULT:SIGNED(WIDTH-1 DOWNTO 0);
	SIGNAL ATAN,ZRESULT:SIGNED(19 DOWNTO 0);
	SIGNAL ZNEG,ZPOS:STD_LOGIC;
 --开始真正的计算所需要的
	BEGIN
	DX<=DELTA(XI,PIPEID);  --调用函数求出2^-nXN并将函数的返回值赋值给DX
	DY<=DELTA(YI,PIPEID);    --调用函数求出2^-nYN并将函数的返回值赋值给DY
	ATAN<=CONV_SIGNED(CATAN(PIPEID),20);  --实际就是调用函数求出弧度数并转换成20位有符号数
 --GENERATE ADDER STRUCTURES
	ZNEG<=ZI(19);
	ZPOS<=NOT ZI(19);  --将符号位给他,即是旋转的方向
 --XADD
	XRESULT<=ADDSUB(XI,DY,ZNEG);  --求出Xn+1
 --YADD
	YRESULT<=ADDSUB(YI,DX,ZPOS);--求出Yn+1
 --ZADD
	ZRESULT<=ADDSUB(ZI,ATAN,ZNEG);  --求出Zn+1
	GEN_REGS:PROCESS(CLK)IS
	BEGIN
	IF(CLK'EVENT AND CLK='1')THEN
		IF(ENA='1')THEN
		XO<=XRESULT;
		YO<=YRESULT;
		ZO<=ZRESULT;
		END IF;
	END IF;
 END PROCESS GEN_REGS;
 END ARCHITECTURE ART;
--SINANDCOS.VHD
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
ENTITY SINANDCOS_CORDIC IS
   	PORT(CLK:IN STD_LOGIC;
			  ENA:IN STD_LOGIC;
			  AIN:IN SIGNED(15 DOWNTO 0);
			  SIN:OUT SIGNED(15 DOWNTO 0);
			  COS:OUT SIGNED(15 DOWNTO 0));
END ENTITY SINANDCOS_CORDIC;
ARCHITECTURE ART OF SINANDCOS_CORDIC IS
	CONSTANT PIPELENGTH:NATURAL:=15;
	CONSTANT P:SIGNED(15 DOWNTO 0):=X"4DBA";
	COMPONENT CORDIC IS
	GENERIC(PIPELINE:INTEGER:=15;
					 WIDTH:INTEGER:=16);
	PORT(CLK:IN STD_LOGIC;
			  ENA:IN STD_LOGIC;
			  XI:IN SIGNED(WIDTH-1 DOWNTO 0);
			  YI:IN SIGNED(WIDTH-1 DOWNTO 0):=(OTHERS=>'0');
			  XO:OUT SIGNED(WIDTH-1 DOWNTO 0);			  ZI:IN SIGNED(WIDTH-1 DOWNTO 0);

			  YO:OUT SIGNED(WIDTH-1 DOWNTO 0));
	END COMPONENT CORDIC;
	BEGIN
	U1:CORDIC
		GENERIC MAP(PIPELINE=>PIPELENGTH,WIDTH=>16)
		PORT MAP(CLK=>CLK,ENA=>ENA,XI=>P,
							ZI=>AIN,XO=>COS,YO=>SIN);
END ARCHITECTURE ART;

 

--TOP.VHD
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY TOP IS
	PORT(K1,K2,K3,K4,K5,K6,ENA,CLK,CLK1:IN STD_LOGIC;	  
		  COM:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
		  SEG:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END ENTITY TOP;
ARCHITECTURE ART OF TOP IS

COMPONENT SINANDCOS_CORDIC IS
	PORT(CLK:IN STD_LOGIC;
			  ENA:IN STD_LOGIC;
			  AIN:IN STD_LOGIC_VECTOR(15 DOWNTO 0);
			  SIN:OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
			  COS:OUT STD_LOGIC_VECTOR(15 DOWNTO 0));
END COMPONENT SINANDCOS_CORDIC;

	COMPONENT DISPLAY IS
		PORT(SEL:IN STD_LOGIC_VECTOR(2 DOWNTO 0);
			  DATAIN:IN STD_LOGIC_VECTOR(15 DOWNTO 0);
			  COM: OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
			  SEG: OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
	END COMPONENT DISPLAY;	
	
COMPONENT CTRLS IS
  PORT(CLK: IN STD_LOGIC;      
  SEL: OUT STD_LOGIC_VECTOR(2 DOWNTO 0));
END COMPONENT CTRLS;

COMPONENT XUAN IS
PORT(K1,K2:IN STD_LOGIC;
	  X0,Y0:IN STD_LOGIC_VECTOR(15 DOWNTO 0);
	  DOUT:OUT STD_LOGIC_VECTOR(15 DOWNTO 0));
END COMPONENT XUAN;

COMPONENT XUANIN IS
PORT(K1,K2,K3:IN STD_LOGIC;
	  DOUT:OUT STD_LOGIC_VECTOR(15 DOWNTO 0));
END COMPONENT XUANIN;

COMPONENT KG IS
  PORT(A,B:IN STD_LOGIC_VECTOR(15 DOWNTO 0);
       K:IN STD_LOGIC;
		 C:OUT STD_LOGIC_VECTOR(15 DOWNTO 0));
END COMPONENT KG;

SIGNAL S1,S3,S4,S5,S7:STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL S2:STD_LOGIC:='1';
SIGNAL S6:STD_LOGIC_VECTOR(2 DOWNTO 0);

	BEGIN
	U2:XUANIN  PORT MAP(K1,K2,K3,S1);
	U3:SINANDCOS_CORDIC  PORT MAP(CLK,S2,AIN=>S1,SIN=>S3,COS=>S4);
	U4:XUAN  PORT MAP(K4,K5,S3,S4,S5);
	U5:CTRLS  PORT MAP(CLK1,S6);
	U6:DISPLAY PORT MAP(S6,S7,COM,SEG);
	U7:KG PORT MAP(S5,S1,K6,S7);
END ARCHITECTURE ART;
--XUANIN.VHD
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
ENTITY XUANIN IS
PORT(K1,K2,K3:IN STD_LOGIC;
	  DOUT:OUT STD_LOGIC_VECTOR(15 DOWNTO 0));
END ENTITY XUANIN;
ARCHITECTURE ART OF XUANIN IS
SIGNAL K:STD_LOGIC_VECTOR(2 DOWNTO 0);
BEGIN
PROCESS (K1,K2,K3) IS
BEGIN
	K<=K1&K2&K3;
	CASE K IS
	WHEN "000"=>DOUT<="0000111000111000";    --0E38  20
	WHEN "001"=>DOUT<="0000000000000000";    --0000 0
	WHEN "010"=>DOUT<="0001010101010101";    --1555 30
	WHEN "011"=>DOUT<="0010000000000000";    --2000 45
	WHEN "100"=>DOUT<="0010101010101010";    --2AAA 60
	WHEN "101"=>DOUT<="0011111111111111";    --3FFF 90
	WHEN "110"=>DOUT<="0001110001110001";    --1C71 40
	WHEN "111"=>DOUT<="0000011100011100";    ---071C 10
	WHEN OTHERS=>DOUT<="0000000000000000";
	END CASE;
END PROCESS;
END ARCHITECTURE ART;
--XUAN.VHD
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
ENTITY XUAN IS
PORT(K1,K2:IN STD_LOGIC;
	  X0,Y0:IN STD_LOGIC_VECTOR(15 DOWNTO 0);
	  DOUT:OUT STD_LOGIC_VECTOR(15 DOWNTO 0));
END ENTITY XUAN;
ARCHITECTURE ART OF XUAN IS
SIGNAL K:STD_LOGIC_VECTOR(1 DOWNTO 0);
BEGIN
PROCESS (K1,K2,X0,Y0) IS
BEGIN
	K<=K1&K2;
	CASE K IS
	WHEN "01"=>DOUT<=X0;--cos的值
	WHEN "10"=>DOUT<=Y0;
	WHEN OTHERS=>DOUT<="0000000000000000";
	END CASE;
END PROCESS;
END ARCHITECTURE ART;
--KG.VHD
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY KG IS
  PORT(A,B:IN STD_LOGIC_VECTOR(15 DOWNTO 0);
       K:IN STD_LOGIC;
		 C:OUT STD_LOGIC_VECTOR(15 DOWNTO 0));
END ENTITY KG;

ARCHITECTURE ART OF KG IS
  BEGIN
  PROCESS(A,B,K)IS
    BEGIN
	 IF K='1' THEN
	   C<=A;
	 ELSE
	   C<=B;
	 END IF;
  END PROCESS;
END ARCHITECTURE ART;
--DISPLAY.VHD
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY DISPLAY IS
  PORT(SEL: IN STD_LOGIC_VECTOR(2 DOWNTO 0);
       DATAIN: IN STD_LOGIC_VECTOR(15 DOWNTO 0);
       COM: OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
       SEG: OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END ENTITY DISPLAY;
ARCHITECTURE ART OF DISPLAY IS
  SIGNAL DATA:STD_LOGIC_VECTOR(3 DOWNTO 0);
  BEGIN
  PROCESS(SEL) IS
    BEGIN
    CASE SEL IS
      WHEN "000" =>COM<="11111110";
      WHEN "001" =>COM<="11111101";
      WHEN "010" =>COM<="11111011";
      WHEN "011" =>COM<="11110111";
      WHEN "100" =>COM<="11101111";
      WHEN "101" =>COM<="11011111";
      WHEN "110" =>COM<="10111111";
      WHEN "111" =>COM<="01111111";
      WHEN OTHERS =>COM<="11111111";
    END CASE ;
  END PROCESS;
  PROCESS(SEL) IS
    BEGIN
    CASE SEL IS
      WHEN "000" =>DATA<=DATAIN(3 DOWNTO 0);				
      WHEN "001" =>DATA<=DATAIN(7 DOWNTO 4);		             
      WHEN "010" =>DATA<=DATAIN(11 DOWNTO 8);
      WHEN "011" =>DATA<=DATAIN(15 DOWNTO 12);		                 					
      WHEN OTHERS=>DATA<="0000";
    END CASE;
       CASE DATA IS
      WHEN"0000"=>SEG<="00111111";
			WHEN"0001"=>SEG<="00000110";
			WHEN"0010"=>SEG<="01011011";
			WHEN"0011"=>SEG<="01001111";
			WHEN"0100"=>SEG<="01100110";
			WHEN"0101"=>SEG<="01101101";
			WHEN"0110"=>SEG<="01111101";
			WHEN"0111"=>SEG<="00000111";
			WHEN"1000"=>SEG<="01111111";
			WHEN"1001"=>SEG<="01101111";
			WHEN"1010"=>SEG<="01110111";
			WHEN"1011"=>SEG<="01111100";
			WHEN"1100"=>SEG<="00111001";
			WHEN"1101"=>SEG<="01011110";
			WHEN"1110"=>SEG<="01111001";
			WHEN"1111"=>SEG<="01110001";
			WHEN OTHERS=>SEG<="00000000";
   END CASE ;
 END PROCESS;
END ARCHITECTURE ART;
--CTRLS.VHD 动态控制信号产生模块
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY CTRLS IS
  PORT(CLK: IN STD_LOGIC;      
  SEL: OUT STD_LOGIC_VECTOR(2 DOWNTO 0));
END ENTITY CTRLS;
ARCHITECTURE ART OF CTRLS IS
  SIGNAL CNT: STD_LOGIC_VECTOR(2 DOWNTO 0);
  BEGIN
  PROCESS(CLK) IS
    BEGIN
    IF CLK'EVENT AND CLK='1' THEN
      IF CNT="111" THEN 
         CNT<="000";
       ELSE 
         CNT<=CNT+'1';
      END IF ;
   END IF;
  END PROCESS;
  SEL<=CNT;
END ARCHITECTURE ART;

        4.  软硬件实验系统构建

整体RTL视图

SINANDCOS模块仿真

实物 COS45°量化值

 正弦和余弦函数求解过程中有关参数及量化值对照表 

  • 15
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值